这篇文章先补充两个AOP的概念:
一)引入(Introduction)
什么是引入?引入是在不修改目标对象的源代码的情况下,为目标对象增加方法和属性一种技术手段。
比如你有如下目标对象:
我们现在要在不修改DoOneThing的基础上,对其增添一个名叫doOtherThing()的方法。那么我们该如何将doOtherThing()引入呢?
首先,将要新增加的方法声明放在新的接口中。
然后编写引入类,实现拦截器IntroductionInterception和新方法接口。
最后,配置引入类
这样用户调用方法时,拦截器IntroductionInterception将方法拦截,判断所调用方法是否为新方法接口里的方法。如果为true,则会让其去调用该方法是实现,否则让其去继续调用原先的方法。
注:1、将拦截器实现和新方法接口名注入到DefaultIntroductionAdvisor中。
2、只能用构造器注入。
3、Spring的引入在性能上有缺陷所以应该尽量少用。
二)织入(Weaving)
把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象的过程叫做织入。这可以在编译时、载入类时、运行时完成(使用AspectJ编译器)。而Spring和其他纯Java AOP框架一样,在运行时完成织入。
大白话,织入就是AOP实现的过程,也就是在内存中动态生成的类那个时间点。回想下不管是动态代理还是CGLIB,这个过程都是必须的。
一)引入(Introduction)
什么是引入?引入是在不修改目标对象的源代码的情况下,为目标对象增加方法和属性一种技术手段。
比如你有如下目标对象:
public class DoThingBean {
public void DoOneThing(){
System.out.println("Do one thing!");
}
}我们现在要在不修改DoOneThing的基础上,对其增添一个名叫doOtherThing()的方法。那么我们该如何将doOtherThing()引入呢?
首先,将要新增加的方法声明放在新的接口中。
public interface IOtherBean {
public void doOtherThing();
} 然后编写引入类,实现拦截器IntroductionInterception和新方法接口。
public class SomeBeanIntroductionInterceptor implements IOtherBean, IntroductionInterceptor {
public void doOtherThing() {
System.out.println("do other thing!");
}
public Object invoke(MethodInvocation invocation) throws Throwable {
//判断调用的方法是否为指定类中的方法
if ( implementsInterface(invocation.getMethod().getDeclaringClass()) ) {
return invocation.getMethod().invoke(this, invocation.getArguments());
}
return invocation.proceed();
}
/**
* 判断clazz是否为给定接口IOtherBean的实现
*/
public boolean implementsInterface(Class clazz) {
return clazz.isAssignableFrom(IOtherBean.class);
}
}最后,配置引入类
<!-- 目标对象 -->
<bean id="someBeanTarget" class="aop.spring.introduction.SomeBeanImpl" />
<!-- 通知 -->
<bean id="someBeanAdvice" class="aop.spring.introduction.SomeBeanIntroductionInterceptor" />
<!-- 通知者,只能以构造器方法注入-->
<bean id="introductionAdvisor" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg ref="someBeanAdvice" />
<constructor-arg value="aop.spring.introduction.IOtherBean" />
</bean>
<!-- 代理 (将我们的切面织入到目标对象)-->
<bean id="someBeanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 若目标对象实现了代理接口,则可以提供代理接口的配置 -->
<property name="proxyInterfaces" value="aop.spring.introduction.ISomeBean" />
<!-- 配置目标对象 -->
<property name="target" ref="someBeanTarget" />
<!-- 配置切面 -->
<property name="interceptorNames">
<list>
<value>introductionAdvisor</value>
</list>
</property>
</bean>这样用户调用方法时,拦截器IntroductionInterception将方法拦截,判断所调用方法是否为新方法接口里的方法。如果为true,则会让其去调用该方法是实现,否则让其去继续调用原先的方法。
注:1、将拦截器实现和新方法接口名注入到DefaultIntroductionAdvisor中。
2、只能用构造器注入。
3、Spring的引入在性能上有缺陷所以应该尽量少用。
二)织入(Weaving)
把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象的过程叫做织入。这可以在编译时、载入类时、运行时完成(使用AspectJ编译器)。而Spring和其他纯Java AOP框架一样,在运行时完成织入。
大白话,织入就是AOP实现的过程,也就是在内存中动态生成的类那个时间点。回想下不管是动态代理还是CGLIB,这个过程都是必须的。
本文详细解释了AOP中的引入和织入概念,通过实例展示了如何在不修改目标对象源代码的情况下为其增加方法和属性。重点介绍了如何在Spring框架下实现这一过程,包括引入类、通知、通知者及代理的配置。
1409

被折叠的 条评论
为什么被折叠?



