Spring AOP,即面向切面思想。使用切面来处理一些问题需要考虑:从哪里进行切入、在什么时候切入以及切面增加什么行为。整个AOP体系可以梳理为下图:
其中设计到的常用术语包括:
Spring AOP的原理总结来说,就是动态代理。采用代理模式,生成一个个代理类,然后替换掉真是实现类来对外提供服务。Spring AOP就是通过getBean()方法返回代理类的实例。该代理类是Spring采用JDK Proxy或CGLIB动态生成的。
1、JDK动态代理
介绍:
Spring默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理。JDK实现动态代理需要两个组件,首先第一个就是InvocationHandler接口。我们在使用JDK的动态代理时,需要编写一个类,去实现这个接口,然后重写invoke方法,这个方法其实就是我们提供的代理方法。然后JDK动态代理需要使用的第二个组件就是Proxy这个类,我们可以通过这个类的newProxyInstance方法,返回一个代理对象。生成的代理类实现了原来那个类的所有接口,并对接口的方法进行了代理,我们通过代理对象调用这些方法时,底层将通过反射,调用我们实现的invoke方法。
优点:
缺点:
2、CGLib动态代理
介绍:
JDK的动态代理存在限制,那就是被代理的类必须是一个实现了接口的类,代理类需要实现相同的接口,代理接口中声明的方法。若需要代理的类没有实现接口,此时JDK的动态代理将没有办法使用,Spring就会使用CGLib的动态代理来生成代理对象。CGLib直接操作字节码,生成类的子类,重写类的方法完成代理。
优点:
缺点:
Spring AOP的关键类就是DefaultAdvisorAutoProxyCreator。该类能自动将所有的advisor生效。通过查看该类的继承结构,惊喜地发现,最后居然是BeanPostProcessor。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
上面是BeanPostProcessor的源码。其两个方法分别在init-method的前后得到执行。体现在Spring IOC中如下所示:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// ...
if (instanceWrapper == null) {
// 1、创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ...
try {
// 2、装载属性
populateBean(beanName, mbd, instanceWrapper);
// 3、初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// ...
}
在AbstractAutowireCapableBeanFactory类中,对refresh()的最后一步,初始化所有的Singleton beans时,在第三步——执行bean初始化方法中,调用BeanPostProcessor的两个方法,来执行增强策略。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// ...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor的postProcessBeforeInitialization()
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用bean配置中的init-method="xxx"
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 执行BeanPostProcessor的postProcessAfterInitialization()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
知道Spring AOP在哪里生效了,现在需要知道的就是如何完成的代理增强。通过查看DefaultAdvisorAutoProxyCreator的代理结构,从AbstractAutoProxyCreator中找到了对BeanPostProcessor两个方法的复写。
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !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;
}
}
// TargetSource——用于封装真实实现类的信息
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
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;
}
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;
}
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
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, 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()
// specificInterceptors:携带了所有的advisors;targetSource:携带了真实实现类的信息
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 设定动态代理方式:
// 配置方式为proxy-target-class属性,默认为false,表示使用JDK动态代理;如果设为true,代表使用CGLIB
// 如果使用CGLIB,增加以下逻辑
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 返回匹配了当前bean的advisors数组
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}