spring aop 源码分析

前置知识

  • spring ioc 容器
  • spring bean 的生命周期
  • spring 中常见类的作用
  • spring aop 的基本使用
  • cglib 动态代理知识
  • jdk 动态代理知识

源码分析

一切皆是 BeanPostProcessor

了解过spring框架的同学都知道, spring中很多功能都是通过实现BeanPostProcessor接口,

在创建bean之后的初始化方法中, 有applyBeanPostProcessorsAfterInitialization方法

1
2
3
4
5
6
7
8
9
10
11
12
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

// 代码省略

if (mbd == null || !mbd.isSynthetic()) {
// after Initialization
// bean初始化之后, 调用beanPostProcessor, 得到包装后的对象
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

AbstractAutoProxyCreator实现了BeanPostProcessor接口

AbstractAutoProxyCreator

在初始化bean完成之后, AbstractAutoProxyCreatorpostProcessAfterInitialization方法就会判断是否需要对当前的bean进行封装代理

1
2
3
4
5
6
7
8
9
10
11
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 先找一下缓存中是否已经处理过了
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

继续往里看 wrapIfNecessary方法,这个方法将返回代理类(如果需要代理的话)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果对象已经被代理过了
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)){
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 返回匹配当前 bean 的所有的 advisor、advice、interceptor(非cglib中的interceptor)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果specificInterceptors不为null
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
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;
}

我们查看一下createProxy, 该方法通过创建一个ProxyFactory来进行代理对象的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable 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);
}
}

// 将所有interceptor装配为Advisor, 并且添加到proxyFactory中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// ProxyFactory中有个成员变量叫AdviceSupport
// advisors保存在AdviceSupport中的List<Advisor> advisors
proxyFactory.addAdvisors(advisors);
// 设置目标source
proxyFactory.setTargetSource(targetSource);
// 模板方法, 子类可以实现
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}

return proxyFactory.getProxy(getProxyClassLoader());
}

getProxy方法主要是获取AopProxy并生成代理对象, 返回的AopProxyCglibAopProxy或者JdkDynamicAopProxy, 即我们常知道的jdk动态代理和cglib动态代理

1
2
3
4
5
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy()
// 生成代理对象
.getProxy(classLoader);
}

ProxyCreatorSupport

AbstractAutoProxyCreator继承自ProxyCreatorSupport, ProxyCreatorSupport有一个默认构造方法, 创建了一个默认的 DefaultAopProxyFactory

1
2
3
4
5
6
// DefaultAopProxyFactory implements AopProxyFactory

// 无参构造
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}

在其中的createAopProxy该方法获取了一个AopProxyFactory并使用该对象创建并返回一个AopProxy,

其中的AopProxyFactory就是构造方法默认创建的DefaultAopProxyFactory, 使用该对象创建了AopProxy

1
2
3
4
5
6
7
8
9
10
11
protected final synchronized AopProxy createAopProxy() {
// 激活此代理配置
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}

DefaultAopProxyFactory

DefaultAopProxyFactoryAopProxyFactory的一个实现, 主要功能就是创建AopProxy, 主要决定使用jdk代理还是cglib进行代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 是否配置了优化代理的策略
// 是否强制使用代理类(注解中指定了true, @EnableAspectJAutoProxy(proxyTargetClass = true))
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.");
}
// 如果代理的对象是接口
// 或者已经被jdk进行代理过了
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// 使用jdk
return new JdkDynamicAopProxy(config);
}
// Objenesis 在spring-core引入了源码
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}

AopProxy

AopProxy:用来实际生成proxy对象的接口,通过DefaultAopProxyFactory类获取

通过下面的类图我们看到AopProxy有两种实现

  • CglibAopProxy cglib的动态代理

  • JdkDynamicAopProxy 基于jdk的动态代理

1
2
3
4
5
6
public interface AopProxy {

Object getProxy();
// 一般需要指定类加载器, 如果类加载器不同导致加载同一个类是有问题的(详见: jvm类加载机制)
Object getProxy(@Nullable ClassLoader classLoader);
}

package org.aopalliance.aop

spring aop的核心接口

简单使用aop

  • ProxyFactoryBean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Bean
public ProxyFactoryBean userServiceProxyBean(UserServiceImpl userServiceImpl) throws ClassNotFoundException {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();

proxyFactoryBean.setProxyInterfaces(new Class[]{UserService.class});
proxyFactoryBean.setTarget(userServiceImpl);
proxyFactoryBean.setInterceptorNames("oneInterceptor");

return proxyFactoryBean;
}
@Component
@Slf4j
public class OneInterceptor implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
log.info("MethodBeforeAdvice before invoke");
}
}

// userServiceProxyBean是FactoryBean(详见: FactoryBean和BeanFactory)
// spring在调用getBean的时候会判断, 如果是FactoryBean, 则调用getObject方法得到代理对象, 不是我们注入的FactoryBean
UserService userService = (UserService) context.getBean("userServiceProxyBean");
// 使用&可以获取 userServiceProxyBean, 不是代理过后的对象
context.getBean("&userServiceProxyBean");
  • BeanNameAutoProxyCreator
1
2
3
4
5
6
7
8
9
10
@Bean
public BeanNameAutoProxyCreator userServiceProxyBeanCreator() {
BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
creator.setBeanNames("userServiceImpl");
creator.setInterceptorNames("oneInterceptor");

return creator;
}
// 自动代理接口
UserService userService = context.getBean(UserService.class);

总结

  • spring aop就是在bean进行初始化之后, 调用实现了PostProcessor接口的类中的postProcessAfterInitialization, 在实现类中依据具体的代码实现代理逻辑
  • spring会根据具体情况选择jdk代理或者cglib代理

声明

如有错误请联系作者更正

参考

  1. Spring AOP各个组件概述与总结