众所周知,spring1.0 与2.0版本的aop实现方式是不同的。
但是依据spring中不重复设计轮子的原则,这两种实现方式的底层代码一定存在着相同的地方,本篇文章就找出spring aop实现中通用的地方。
spring1.2的aop配置方式:
<bean id="myAdvisor" class="com.mycompany.MyAdvisor">
<property name="someProperty"><value>Custom string property value</value></property>
</bean>
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>
<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.mycompany.Person</value></property>
<!-- Use inner bean, not local reference to target -->
<property name="target">
<bean class="com.mycompany.PersonImpl">
<property name="name"><value>Tony</value></property>
<property name="age"><value>51</value></property>
</bean>
</property>
<property name="interceptorNames">
<list>
<value>myAdvisor</value>
<value>debugInterceptor</value>
</list>
</property>
</bean>
spring AspectJ实现方式分为两种,一种是在spring配置文件中,配置类似:
<aop:config>
<aop:pointcut id="manPointcut"
expression="execution(* com.licg.tx.*Impl.*(..))" />
<aop:aspect id="beforeExample" ref="fbi">
<aop:before pointcut-ref="manPointcut" method="before" />
<aop:after pointcut-ref="manPointcut" method="before" />
</aop:aspect>
<aop:aspect id="before2" ref="fbi2">
<aop:before pointcut-ref="manPointcut" method="before" />
</aop:aspect>
</aop:config>
另外一种就是:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("execution(* com.xyz.myapp.dao.*.*(..))")
public void doAccessCheck() {
// ...
}
好的,先研究加载代理bean的方式
从1.2配置文件中我们可以直接看出来,spring代理bean是通过ProxyFactoryBean这个创建代理类的工厂创建出来的。我们只需要将我们需要代理的bean的Advisor或者Advice配置到ProxyFactoryBean这个代理工厂下面,spring便为我们生成了代理的bean。
那么我们通过aspectj配置的代理bean是如何加载的呢?
好的我们用eclipse配置spring项目,我们打开spring源代码:
org.springframework.aop.aspectj.AspectJMethodBeforeAdvice 给构造器打上断点,
org.springframework.aop.aspectj.AspectJPointcutAdvisor 给构造器打上断点。
采用debug模式启动,你会惊讶的发现,spring会把aspectj方式所配置的aspectj首先转化为pointcut对象,然后转换成Advice对象,最后转换成Advisor 对象。
ok,到这个时候恐怕大家已经发现了,spring AspectJ的代理方式底层的实现上和spring1.2配置方式实现上竟然一致了,都是先将要代理的bean转化为Advisor或者Advice。
那么再以后的操作也就相同了,都是通过ProxyFactoryBean这个代理工厂实现代理bean的生成。
着重说明几点:
1.AspectJMethodBeforeAdvice 与AspectJPointcutAdvisor 这个类的发现大家可以看spring log4j的日子打印,与debug的类调试走向。
2.通过spring aspectj配置的advice的方法中可以带的实现对象的参数为:
JoinPoint,ProceedingJoinPoint,JoinPoint.StaticPart
具体查看spring AbstractAspectJAdvice类源代码。
3.AspectJMethodBeforeAdvice 与AspectJPointcutAdvisor 这两个类,我们可以通过查找子类,查询父类,查询接口查看spring的源代码的相关实现。