当使用Spring事务时,需要在Spring的配置文件中添加命名空间aop
xmlns:aop="http://www.springframework.org/schema/aop"
aop命名空间的处理类可在Spring-aop-XXXXX.jar中找到。
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
AopNamespaceHandler的代码如下
public class AopNamespaceHandler extends NamespaceHandlerSupport {
/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
上面的代码标识了不同标签的处理类。
aspectj-autoproxy的处理类为
org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser
AspectJAutoProxyBeanDefinitionParser的解析过程如下:
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
}
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary函数主要向Spring注入AnnotationAwareAspectJAutoProxyCreator类
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
下面来看AnnotationAwareAspectJAutoProxyCreator类。
欲观察AnnotationAwareAspectJAutoProxyCreator如何起作用的,一般而言观察AnnotationAwareAspectJAutoProxyCreator实现了Spring的那些Aware或者回到函数。
通过观察可发现AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口。
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
下面来看AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInitialization做了什么事
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
Nothing。
postProcessAfterInitialization呢?
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
下面来看wrapIfNeccessary函数
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//部分代码略
//1.找到当前对象的advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//2.代理当前对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
主要做两件事:
- 找到当前对象的Advisor。
- 对当前对象进行代理。
getAdvicesAndAdvisorsForBean会调用到
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findEligibleAdvisors处理两件事:
- findCandidateAdvisors找到Spring中所有的Advisor.
- findAdvisorsThatCanApply过滤出适合当前对象的advisors.
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
findEligibleAdvisors处理两件事
- 找到Spring中Advisor的实现类(findCandidateAdvisors)
- 将所有拥有@Aspect注解的类转换为advisors(aspectJAdvisorsBuilder.buildAspectJAdvisors)
注:
通过aspect注解生成Advisor时,如果同一个函数上有多个aspect注解,比如同时有@After @Before注解,只有@Before注解起作用。(为毛如此设计?)
findAdvisorsThatCanApply
找到当前对象适合的所有Advisor。整个过程比较简单:
遍历所有的advisor。
查看当前advisor的pointCut是否适用于当前对象,如果是,假如候选队列,否则跳过。
createProxy
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
该函数的逻辑
- 初始化ProxyFactory
- 调用proxyFactory.getProxy生成代理对象
初始化ProxyFactory时需要注意ProxyTargetClass的初始化,proxyTargetClass的值决定了代理模式是cglib还是jdk动态代理。
proxyTargetClass的值:
if 设置了proxy-target-class=“true”
then proxyTargetClass=true,使用cglib代理。
else if(当前对象实现了用户自定义的接口)
then proxyTargetClass=false,使用JDK动态代理
else
proxyTargetClass=true,使用cglib代理。
getProxy
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
createAopProxy根据proxyTargetClass等内容决定使用cglib还是jdk动态代理。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
getProxy函数就是使用cglib还是jdk动态代理 生成代理对象过程。
具体代理过程可查看
- cglib
Object org.springframework.aop.framework.CglibAopProxy.getProxy(ClassLoader classLoader)
- JDK动态代理
Object org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(ClassLoader classLoader)