spring源码AOP解析
2018-11-20 03:20:30来源:博客园 阅读 ()
1、代理技术(静态代理、JDK动态代理、CGLib代理)
静态代理: |-- Hello |-- void say(String name); |-- HelloImpl implements Hello { voiv say(String name){ sysout("Hello!"+name); } } |-- HelloProxy implents Hello { Hello hello; HelloProxy(){ hello = new HelloImpl(); } voiv say(String name){ before(); sysout("Hello!"+name); end(); } void before(){ sysout("Before"); } void after(){ sysout("After"); } main(String[] args){ Hello hello = new HelloProxy(); hello.say("Jack"); } } JDK动态代理: |-- DynamicProxy implements InvocationHandler { Object target; DynamicProxy (Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args){ before(); object result = method.invoke(target, args); after(); return result; } ... main(String[] args){ // 尝试1 Hello hello = new HelloImpl(); DynamicProxy dynamicProxy = new DynamicProxy(hello); Hello hello = (Hello)Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass.getInterfaces(), dynamicProxy); hello.say("Jack"); // 尝试2 DynamicProxy dynamicProxy = new DynamicProxy(new HelloImpl()); Hello hello = dynamicProxy.getProxy(); hello.say("Jack"); } public <T> T getProxy(){ return (T)Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass.getInterfaces(), this ); } } CGLib动态代理: |-- CGLibProxy implements MethodInterceptor { private static CGLibProxy instance = new CGLibProxy(); private CGLibProxy() {} public CGLibProxy getInstance(){ return instance; } public <T> T getProxy(Class<T> cls){ return (T) Enhancer.create(cls, this); } public Object inercept(Object obj, Method method, Object[] args, MethodProxy proxy){ before(); Object result = proxy.invokeSuper(obj, args); after(); return result; } ... main(String[] args){ // 尝试1 CGLibProxy cgLibProxy = new CGLibProxy(); Hello helloProxy = cgLibProxy.getProxy(HelloImpl.class); helloProxy.say("Jack"); // 尝试2 Hello helloProxy =CGLibProxy.getInstance().getProxy(HelloImpl.class); helloProxy.say("Jack"); } }
2、AOP技术
|-- interface Greeting |-- void sayHello(String name); |-- GreetingImpl implements Greeting |-- sayHello(String name){ before(); sysout("Hello!"+name); after(); } |-- GreetingProxy implements Greeting |-- GreetingImpl greetingImpl; |-- GreetingProxy(GreetingImpl greetingImpl) -> this.greetingImpl = greetingImpl; |-- sayHello(String name){ before(); greetingImpl.sayHello(); after(); } |-- before() -> sysout("Before"); |-- after() -> sysout("After"); |-- main(String[] args){ Greeting greetingProxy = new GreetingProxy(new GreetingImpl()); greetingProxy.sayHello("Jack"); } |-- JDKDynamicProxy implements InvocationHandler { Object target; JDKDynamicProxy (Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args){ before(); object result = method.invoke(target, args); after(); return result; } public <T> T getProxy(){ return (T)Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass.getInterfaces(), this ); } private void before(){ sysout("Before"); } private void after(){ sysout("After"); } main(String[] args){ Greeting greeting = new JDKDynamicProxy(new GreetingImpl()).getProxy(); greeting.sayHello("Jack"); } } |-- CGLibProxy implements MethodInterceptor{ private static CGLibProxy instance = new CGLibProxy(); private CGLibProxy() {} public CGLibProxy getInstance(){ return instance; } public <T> T getProxy(Class<T> cls){ return (T) Enhancer.create(cls, this); } public Object inercept(Object obj, Method method, Object[] args, MethodProxy proxy){ before(); Object result = proxy.invokeSuper(obj, args); after(); return result; } main(String[] args){ Greeting greeting = CGLibProxy.getInstance().getProxy(GreetingImpl.class); greeting.sayHello("Jack"); } }
3、spring AOP技术
|-- GreetingBeforeAdvice implements MethodBeforeAdvice |-- before(Method method, Object[] args, Object target) throws Throwable -> sysout("Before"); |-- AfterReturningAdvice |-- afterReturning(Object result, Method method, Object[] args, Object target) throws Throwable -> sysout("after"); |-- GreetingBeforeAndAfterAdvice implements MethodBeforeAdvice, AfterReturningAdvice |-- before(Method method, Object[] args, Object target) throws Throwable -> sysout("Before"); |-- afterReturning(Object result, Method method, Object[] args, Object target) throws Throwable -> sysout("after"); |-- GreetingAroundAdvice implements MethodInterceptor // 环绕增强(org.aopalliance.intercept.MethodInterceptor,AOP联盟) |-- Object invoke(MethodInvocation invocation){ before(); Object result = invocation.proceed(); after(); } |-- before() -> sysout("Before") |-- after() -> sysout("After") |-- main (String[] args){ ProxyFactory proxyFactory = new ProxyFactory(); // 创建代理工厂 proxyFactory.setTarget(new GreetingImpl()); // 射入目标类对象 // proxyFactory.addAdvice(new GreetingBeforeAdvice()); // 添加前置增强 // proxyFactory.addAdvice(new AfterReturningAdvice()); // 添加后置增强 // proxyFactory.addAdvice(new GreetingBeforeAndAfterAdvice()); // 添加前后置增强 proxyFactory.addAdvice(new GreetingAroundAdvice()); // 添加环绕增强 Greeting greeting = (Greeting)proxyFactory.getProxy(); // 从代理工厂获取代理对象 greeting.sayHello("Jack"); // 调用代理方法 } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为Spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个代理 --> <bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="aop.Greeting"></property><!-- 需要代理的接口 --> <property name="target" value="greetingImpl"></property><!-- 接口实现类 --> <!-- <property name="target" value="greetingAroundAdvice"></property> --> <property name="interceptorNames"> <list> <value>greetingAroundAdvice</value> </list> </property> </bean> spring2.5+特性,@Component @Component public calss GreetingImpl implements Greeting { ... } --> <bean id="xxx" class="xxx"> |-- 客户端调用 |-- main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("aop/demo/spring.xml"); Greeting greeting = (Greeting)context.getBean("greetingProxy"); greeting.sayHello("Jack"); } |-- 抛出增强-ThrowsAdvice |-- GreetingThrowAdvice implements ThrowsAdvice { public void afterThrowing(Method method, Object[] args, Object target, Exception e){ sysout("--------- Throw Exception ---------"); sysout("Target Class: " + target.getClass().getName()); sysout("Method Name: " + method.getName()); sysout("Exception Message: " + e.getMessage()); sysout("-----------------------------------"); } } |-- 引入增强 |-- interface Apology |-- void saySorry(String name); |-- @Component GreetingIntroAdvice extends DelegatingIntroductionInterceptor implements Apology { @Override public Object invoke(MethodInvocation invocation) throws Throwable{ return super.invoke(invocation); } @Overrice public void saySorry(String name){ sysout("Sorry! + name); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为Spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个代理 --> <bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="aop.demo.Apology"></property><!-- 需要动态实现的接口 --> <property name="target" value="greetingImpl"></property><!-- 目标类 --> <property name="interceptorNames" value="greetingIntroAdvice"></property> <!-- 引入增强 --> <property name="proxyTargetClass" value="true"/> <!-- 代理目标类(默认为false,代理接口)--> </bean> |-- 调用 |-- main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("aop/demo/spring.xml"); GeetingImpl greetingImpl = (GeetingImpl)context.getBean("greetingProxy"); // 转型为目标类,而非它的接口 greetingImpl.sayHello("Jack"); Apology apology = (Apology) greetingImpl; // 将目标类型强制向上转型为Apology接口(这就是引入增强给我们带来的特性,也就是“接口动态实现”功能) apology.saySorry("Jack"); } |-- AOP 切面 |-- @Component public class GreetingImpl implements Greeting { @Override public void sayHello(){ sysout("Hello!" + name); } public void goodMorning(String name){ sysout("Good Morning!" + name); } public void goodNight(String name){ sysout("Good Night!" + name); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为Spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个切面 --> <bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" value="greetingAroundAdvice"></property> <!-- 增强 --> <property name="pattern" value="aop.demo.GreetingImpl.good.*"></property> <!-- 切点(正则表达式) --> </bean> <!-- 配置一个代理 --> <bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" value="greetingImpl"></property><!-- 目标类 --> <property name="interceptorNames" value="greetingAdvisor"></property><!-- 切面 --> <property name="proxyTargetClass" value="true"/> <!-- 代理目标类(默认为false,代理接口)--> </bean> |-- AOP自动代理(每一个类都需要配置切面太麻烦,因此需要自动生成代理) |-- 配置文件-spring.xml <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="target" value="*Impl"></property><!-- 目标类 --> <property name="interceptorNames" value="greetingAroundAdvice"></property><!-- 增强 --> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> *Impl -> 不清楚Bean实现了多少接口,不能代理接口,只能代理类。 |-- 匹配到目标类的指定方法 |-- 配置文件-spring.xml <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!-- <property name="target" value="*Impl">--></property><!-- 目标类 --> <!-- <property name="interceptorNames" value="greetingAroundAdvice"></property>--><!-- 增强 --> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> --> <bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="greetingAroundAdvice"></property> <!-- 增强 --> <property name="pattern" value="aop.demo.GreetingImpl.good.*"></property> <!-- 切点(正则表达式) --> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> 总结: CGLib代理:创建代理速度慢,创建代理后运行速度快(系统初始化创建代理备用最佳) JDK动态代理:创建代理速度快,运行速度慢 |-- spring + AspectJ(Advisor) |-- 普通demo |-- @Aspect @Component public class GreetingAspect { @Arount("execution(* aop.demo.GreetingImpl.*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { before(); Object result = pjp.proceed(); after(); return result; } public void before(){ sysout("Before"); } public void after(){ sysout("after"); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为Spring bean) --> <context:componet-scan base-package="aop.demo"/> <aop:aspect-autoproxy proxy-target-class="true" /> |-- 基于注解 |-- @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @Interface Tag { } |-- @Aspect @Component public class GreetingAspect { @Arount("@Annotation(aop.demo.Tag)") public Object around(ProceedingJoinPoint pjp) throws Throwable { ... } ... } |-- @Component public class GreetingImpl implements Greeting { @Tag @Override public void sayHello(String name){ sysout("Hello!" + name); } ... } |-- 实现引入增强 |-- @Aspect @Component public class GreetingAspect { @DelareParents(value="aop.demo.GreetingImpl",defaultImpl="ApologyImpl.class") private Apology apology; } |-- ApologyImpl implements Apology { @Override public void saySorry(String name){ sysout("Sorry!" + name); } main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("aop/demp/spring.xml"); Greeting greeting = context.getBean("greetingImpl"); greeting.sayHello("Jack"); Apology apology = (Apology) greeting; apology.saySorry("Jack"); } } |-- 基于配置 |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为Spring bean) --> <context:componet-scan base-package="aop.demo"/> <beans ...> <bean id="greetingImpl" class="aop.demo.GreetingImpl" /> <bean id="greetingAspect" class="aop.demo.GreetingAspect" /> <aop:config> <aop:aspect ref="greetingAspect"> <aop:around method="around" pointcut="execution (* aop.demo.GreetingImpl.*(..))"/> </aop:aspect> </aop:config> </beans>
4、开发aop框架
|-- 定义注解类: |-- @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @Interface Aspect { Class<? extends Annotion> value(); } |-- 搭建代理框架 |-- interface Proxy { 代理接口 // 执行链式代理:可将多个代理通过一条链子串起来,一个个地去执行,执行顺序取决于添加到链上的先后顺序 Object doProxy(ProxyChain proxyChain) throws Throwable; } |-- class ProxyChain // 代理链 |-- Class<?> targetClass; |-- Object targetObject; }-- Method targetMethod; |-- MethodProxy methodProxy; }-- Object[] methodParams; |-- List<Proxy> proxyList = new ArrayList<>(); |-- int proxyIndex=0; |-- ProxChain(Class<?> targetClass,Object targetObject,Method targetMethod,MethodProxy methodProxy,Object[] methodParams,List<Proxy> proxyList){ this.targetClass = targetClass; ... } |-- getMethodParams() -> return methodParams; |-- getTargetClass() -> return targetClass; |-- getTargetMethod() -> return targetMethod; |-- Object doProxyChain() throws throwable{ Object methodResult; if (proxyIndex < proxyList.size()){ methodResult = proxyList.get(proxyIndex++).doProxy(); } else { methodResult = methodProxy.invokeSuper(targetObject, methodParams); } return methodResult; } |-- 添加pom.xml依赖 <!-- cglib 依赖--> <grouId>cglib<groupId>... |-- class ProxyManger // 代理管理类 |-- <T> T createProxy(final Class<?> targetClass, final List<Proxy> proxyList){ return (T) Enhancer.create(targetClass, new MethodInterceptor(){ @Overrice public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy){ return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList); } }); } |-- public abstract calss AspectProxy implements Proxy { // 切面代理 @Override public final Object doProxy(ProxyChain proxyChain) throws throwable { Object result = null; Class<?> cls = proxyChain.getTargetClass(); Method method = proxyChain.getTargetMethod(); Object[] params = proxyChain.getMethodParams(); begin(); try { if (intercept(cls, method, params)){ before(cls, method, params); result = proxyChain.doProxyChain(); after(cls, method, params); } else { return proxyChain.doProxyChain(); } } catch(Exception e){ logger.error("proxy failure", e); error(cls, method, params, e); throw e; } finally { end(); } } public void begin(){ } public void end(){ } public boolean intercept(Class<?> cls, Method method, Object[] params) throws Throwable { return true; } public void before(Class<?> cls, Method method, Object[] params) throws Throwable { } public void after(Class<?> cls, Method method, Object[] params) throws Throwable { } public void error(Class<?> cls, Method method, Object[] params, Throwable e){ } } |-- @Aspect(Controller.class) ControllerAspect extends AspectProxy{ // 拦截Controller 所有方法 private long begin; @Override public void before(Class<?> cls, Method method, Object[] params) throws Throwable { begin = System.currentTimeMillis(); } @Override public void after(Class<?> cls, Method method, Object[] params) throws Throwable { sysout(System.currentTimeMillis()-begin); } } |-- BeanHelper { ... // 设置bean实例 public static void setBean(Class<?> cls, Object obj){ BEAN_MAP.put(cls, obj); } } |-- ClassHelper { ... // 获取某父类(或接口)的所有子类(或实现类) public static Set<Class<?>> getClassSetBySuper(Class<?> superClass){ Set<Class<?>> classSet = new HashSet<Classs<?>(); for(Class<?> cls : CLASS_SET){ if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)){ classSet.add(cls); } } } // 获取应用包名下带有注解的所有类 public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotionClass){ Set<Class<?>> classSet = new HashSet<Classs<?>(); for(Class<?> cls : CLASS_SET){ if (superClass.isAnnotationPresent(annotionClass)){ classSet.add(cls); } } } ... } |-- AopHelper { ... private static Set<Class<?>> createTargetClassSet(Aspect aspect) throws Exception { Set<Class<?>> targetClassSet = new HashSet<Class<?>>(); Class<? extends annotation> annotation = aspect.value(); if (annotation != null && !annotation.equals(Aspect.class)){ targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation)); } return targetClassSet; } private static Map<Class<?>>,Set<Class<?>>> createProxyMap() throws Exception { Map<Class<?>>,Set<Class<?>>> proxyMap = new HashMap<Class<?>>,Set<Class<?>>>(); Set<Class<?>> proxyClassSet = ClassHelper.getClassSetByAnnotation(AspectProxy.class); for(Class<?> proxyClass : proxyClassSet){ if (proxyClass.isAnnotationPresent(Aspect.class)){ Aspect aspect = proxyClass.getAnnotation(Aspect.class); Set<Class<?>> targetClassSet = createTargetClassSet(aspect); proxyMap.put(proxyClass, targetClassSet); } } return proxyMap; } private static Map<Class<?>,List<Proxy>> createTargetMap(Map<Class<?>>,Set<Class<?>>> proxyMap) throws Exception { Map<Class<?>,List<Proxy>> targetMap = new HashMap<Class<?>,List<Proxy>>(); for(Map.Entry<Class<?>>,Set<Class<?>>> proxyEntry : proxyMap.entrySet()){ Class<?> proxyClass = proxyEntry.getKey(); Set<Class<?> targetClassSet = proxyEntry.getValue(); for(Class<?> targetClass : targetClassSet){ Proxy proxy = (Proxy) targetClass.newInstance(); if (targetMap.contains(targetClass)){ targetMap.get(targetClass).add(proxy); } else { List<Proxy> proxyList = new ArrayList<Proxy>(); proxyList.add(proxy); targetMap.put(targetClass, proxyList); } } } } static { try { Map<Class<?>>,Set<Class<?>>> proxyMap = createProxyMap(); Map<Class<?>,List<Proxy>> targetMap = createTargetMap(proxyMap); for(Map.Entry<Class<?>,List<Proxy>> targetEntry : targetMap.etrySet()){ Class<?> targetClass =targetEntry.getKey(); List<Proxy> proxyList = targetEntry.getValue(); Object proxy = ProxyManager.createProxy(targetClass, proxyList); BeanHelper.setBean(targetClass, proxy); } } catch(Exception e){ Logger.error("aop failure", e); } } } |-- HelperLoader { public static void init(){ Class<?>[] classList = { ClassHelper.class, BeanHelper.class, AopHelper.class, IocHelper.class, ControllerHelper.class }; for(Class<?> cls : classList){ ClassUtil.loadClass(cls.getName(), true); } } }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:进程和线程的区别
下一篇:linux如何正确设置静态ip
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash