代理模式和面向切面编程
2016-06-25 19:58
316 查看
前言:从代理的角度总结Spring AOP
一、静态代理:你不知道我想做什么,我也不关心你做了什么
View Code
四、Spring AOP:面向切面的集大成者
无论是JDK的实现方式还是CGLIB的字节码技术,我们都可以利用Spring AOP做最后的统一处理。要说利用Spring AOP创建代理的唯一不足之处就是,无论被代理对象还是代理对象本身都必须交给Spring容器来管理,如果你仅仅是希望实现一个简单的代理逻辑而并不愿意大范围修改代码,引入Spring显然过于笨重。
一个简单的Service接口
创建ServiceImpl类实现上述接口
编写ServiceB类(没有实现接口的被代理对象)
编写功能齐备的代理逻辑
通过xml文件配置切面、切点和建言。
通过junit演示
之前我曾经写过一篇博客专门总结过spring官方文档有关aop的章节,感兴趣的朋友可以自己查看。
一、静态代理:你不知道我想做什么,我也不关心你做了什么
import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; // 丢失的Shape接口 class Rectangle { public void draw() { System.out.println("Draw Rectangle"); } public void erase() { System.out.println("Erase Rectangle"); } } // 共同的代理逻辑 class Interceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("create Target"); Object o = proxy.invokeSuper(obj, args); System.out.println("destroy Target"); return o; } } public class CglibDemo { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Rectangle.class); enhancer.setCallback(new Interceptor()); Rectangle proxy = (Rectangle) enhancer.create(); proxy.draw(); proxy.erase(); } }
View Code
四、Spring AOP:面向切面的集大成者
无论是JDK的实现方式还是CGLIB的字节码技术,我们都可以利用Spring AOP做最后的统一处理。要说利用Spring AOP创建代理的唯一不足之处就是,无论被代理对象还是代理对象本身都必须交给Spring容器来管理,如果你仅仅是希望实现一个简单的代理逻辑而并不愿意大范围修改代码,引入Spring显然过于笨重。
一个简单的Service接口
package aop; public interface Service { void bar(); }
创建ServiceImpl类实现上述接口
package aop; public class ServiceImpl implements Service { @Override public void bar() { System.out.println("service bar"); } }
编写ServiceB类(没有实现接口的被代理对象)
package aop; public class ServiceB { public void throwException(int type) { System.out.println("service B"); if (type == 1) { throw new IllegalArgumentException("测试异常"); } } }
编写功能齐备的代理逻辑
package aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class AdviceImpl { // 方法前插入 public void doBefore(JoinPoint jp) { System.out.println( "log Begining method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } // 方法后插入 public void doAfter(JoinPoint jp) { System.out.println( "log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } // 前后一起插入的完整逻辑 public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object retVal = pjp.proceed(); time = System.currentTimeMillis() - time; System.out.println("process time: " + time + " ms"); return retVal; } // 捕获异常,相当于把被代理对象放置在try...catch中 public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } }
通过xml文件配置切面、切点和建言。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <aop:config> <aop:aspect id="aspect" ref="aspectBean"> <aop:pointcut id="businessService" expression="execution(* aop.*.*(..))" /> <aop:before pointcut-ref="businessService" method="doBefore" /> <aop:after pointcut-ref="businessService" method="doAfter" /> <aop:around pointcut-ref="businessService" method="doAround" /> <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex" /> </aop:aspect> </aop:config> <bean id="aspectBean" class="aop.AdviceImpl" /> <bean id="service" class="aop.ServiceImpl" /> <bean id="serviceB" class="aop.ServiceB" /> </beans>
通过junit演示
package aop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopTest { @Test public void aop() { ApplicationContext ctx = new ClassPathXmlApplicationContext("aop/spring.xml"); // 查看所有对象是否都正确的交给spring来管理 for (String beanName : ctx.getBeanDefinitionNames()) { System.out.println(beanName); } System.out.println("===============伟大的分割线================"); ServiceB serviceB = (ServiceB) ctx.getBean("serviceB"); serviceB.throwException(1); } }
之前我曾经写过一篇博客专门总结过spring官方文档有关aop的章节,感兴趣的朋友可以自己查看。
相关文章推荐
- C语言标准定义的32个关键字
- ssh整合出现的一些问题总结(spring4+struts2+hibernate4)
- struts2的文件上传和下载
- 代码覆盖率工具 EMMA
- C++设计模式系列之三行为型模式
- c++与stm32串口通信
- 学习Java Web开发中遇到的问题,及其解决方法
- .NET—Spring.NET保持数据现场测试
- ThinkPHP框架学习(1)
- ConcurrentHashMap源代码解读
- 提高项目11-让吃货失望的菜单
- PHP中对于错误信息的提示配置?
- Python的由来
- java之详解匿名内部类
- SpringMVC和Struts2的区别
- 提高项目10-编制三角函数表
- 使用Spring AOP和Cookie做网站免登陆
- 基于布尔注入的Python代码
- Pythagoras's Revenge
- 学习Java中遇到的一些问题