目录
本系列主要分析基于注解形式的SpringAOP实现流程,大致可以分为以下几个核心步骤:
- 解析配置aspectj-autoproxy
- 加载Aspect切面和Advisor
- 创建代理
- 调用代理对象中的方法
Bean创建过程中的postProcessBeforeInstantiation:
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
上文我们分析到getAdvicesAndAdvisorsForBean方法,得到了一个适用于当前Bean的Advisor集合;
接下来继续createProxy方法,即创建代理。
第三步:创建代理
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
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
- 将interceptor统一适配为Advisor
- proxyFactory.getProxy获取代理
1.buildAdvisors统一适配为Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<Object>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isDebugEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
适配方法为advisorAdapterRegistry.wrap:
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
方法中的this.adapters在初始化时注册进去的适配器有:
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
而这三种适配器所支持的Advice类型分别为:
// MethodBeforeAdviceAdapter
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
//AfterReturningAdviceAdapter
public boolean supportsAdvice(Advice advice) {
return (advice instanceof AfterReturningAdvice);
}
//ThrowsAdviceAdapter
public boolean supportsAdvice(Advice advice) {
return (advice instanceof ThrowsAdvice);
}
再来分析wrap方法,将传来的增强器分为了三种:
- Advisor类型,直接返回Advisor;
- Advice类型,包装为DefaultPointcutAdvisor返回;
- MethodInterceptor类型
- MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice类型
在Spring AOP(二)AOPAlliance与SpringAOP核心接口介绍中,我们可以找到这几种名词之间的关系:除了Advisor之外,还有可能是我们直接实现了Advice系列的接口(在Spring的低版本中支持此种方式)。
Spring AOP 使用介绍,从前世到今生
中描述了实现Advice接口的方式;
本节中分析的是基于@Aspect注解的形式,故传入的增强器都是上篇中所述创建的Advisor,直接返回。
2.proxyFactory.getProxy获取代理
proxyFactory.getProxy(getProxyClassLoader());
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
2.1. createAopProxy决定使用Jdk或CgLib方式创建代理
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//config.isOptimize() :是否需要优化,是专门针对于CGlib代理的优化策略,并不推荐属于此配置;
//config.isProxyTargetClass() :检测 proxyTargetClass 的值
//hasNoUserSuppliedProxyInterfaces(config) :是否存在代理接口
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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
决定策略总结来说就是:
- 如果目标对象实现了接口,则优先使用 JDK 代理
- 如果目标对象实现了接口,可以设置proxy-target-class属性为true,强制使用CgLib代理
- 如果目标对象没有实现接口,则必须使用 CGLIB 进行代理
2.2. getProxy创建代理
下篇详细分析两种代理创建的流程