加入收藏 | 设为首页 |

国王的演讲-Spring AOP 源码解析

海外新闻 时间: 浏览:278 次

之前写过 IOC 的源码剖析,那篇文章真的有点长,看完需关键耐性。许多读者期望能写一写 Spring AOP 的源码剖析文章,这样读者看完 IOC + AOP 也就对 Spring 会有比较深的了解了。今日总算成文了,或许许多读者早就不再等待了,不过首要为了后来者吧。

本文不会像 IOC 源码剖析那篇文章相同,很详细地剖析每一行 Spring AOP 的源码,方针读者是现已知道 Spring IOC 源码是怎样回事的读者,由于 Spring AOP 终归是依靠于 IOC 容器来办理的。

阅览主张:1、先搞懂 IOC 容器的源码,AOP 依靠于 IOC 容器来办理。2、细心看完 Spring AOP 运用介绍 这篇文章,先搞懂各种运用办法,你才干"猜到"应该怎样完结。

Spring AOP 的源码并不简略,由于它多,所以阅览源码最好便是找到一个分支,追寻下去。本文定位为蜻蜓点水,看个大约,不详细到每一个细节。

目录:

前语

这一节,咱们先来"猜猜" Spring 是怎样完结 AOP 的。

在 Spring 的容器中,咱们面向的方针是一个个的 bean 实例,bean 是什么?咱们能够简略了解为是 BeanDefinition 的实例,Spring 会依据 BeanDefinition 中的信息为咱们出产适宜的 bean 实例出来。

当咱们需求运用 bean 的时分,经过 IOC 容器的 getBean(…) 办法从容器中获取 bean 实例,只不过大部分的场景下,咱们都用了依靠注入,所以很少手动调用 getBean(...) 办法。

Spring AOP 的原理很简略,便是动态署理,它和 AspectJ 不相同,AspectJ 是直接修改掉你的字节码。

署理形式很简略,接口 + 实在完结类 + 署理类,其间 实在完结类 和 署理类 都要完结接口,实例化的时分要运用署理类。所以,Spring AOP 需求做的是生成这么一个署理类,然后替换掉实在完结类来对外供给服务。

替换的进程怎样了解呢?在 Spring天菜是什么意思 IOC 容器中十分简略完结,便是在 getBean(…) 的时分回来的实际上是署理类的实例,而这个署理类咱们自己没写代码,它是 Spring 选用 JDK Proxy 或 CGLIB 动态生成的。

getBean(…) 办法用于查找或实例化容器中的 bean,这也是为什么 Spring AOP 只能效果于 Spring 容器中的 bean 的原因,关于不是运用 IOC 容器办理的方针,Spring AOP 是力不从心的。

本文运用的调试代码

阅览源码很好用的一个办法便是跑代码来调试,由于自己一行一行地看的话,比较单调,而且难免会漏掉一些东西。

下面,咱们先预备一些简略的调试用的代码。

首要先界说两个 Service 接口:


// OrderService.java
public interface OrderService {

Order createOrder(String username, String product);

Order queryOrder(String username);
}
// UserService.java
public interface UserService {

User createUser(String firstName, String lastName, int age);

User queryUser();
}

然后,别离来一个接口完结类:


// OrderServiceImpl.java
public class OrderServiceImpl implements OrderService {

@Override
public Order createOrder(String username, String product) {
Order order = new Order();
order.setUsername(username);
order.setProduct(product);
return order;
}

@Override
public Order queryOrder(String username) {
Order order = new Order();
order.setUsername("test");
order.setProduct("test");
return order;
}
}

// UserServiceImpl.java
public class UserServiceImpl implements UserService {

@Override
public User createUser(String firstName, String lastName, int age) {
User user = new User();
user.setFirstName(firstName);
user.setLastName(lastName);
user.setAge(age);
return user;
}

@Override
public User queryUser() {
User user = new User();
user.setFirstName("test");
user.setLastName("test");
user.setAge(20);
return user;
}
}

写两个 Advice:


public class LogArgsAdvice implements MethodBeforeAdvice {

@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("预备履行办法: " + method.getName() + ", 参数列表:" + Arrays.toString(args));
}
}
public class LogResultAdvice implements AfterReturningAdvice {

@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
throws Throwable {
System.out.println(method.getName() + "办法回来:" + returnValue);
}
}

装备一下:

咱们这边运用了前面文章介绍的装备 Advisor 的办法,咱们回忆一下。

每个 advisor 内部持有 advice 实例,advisor 担任匹配,内部的 advice 担任完结阻拦处理。装备了各个 advisor 后,装备 DefaultAdvisorAutoProxyCreator 使得一切的 advisor 装备主动收效。

发动:


public class SpringAopSourceApplication {

public static void main(String[] args) {

// 发动 Spring 的 IOC 容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:DefaultAdvisorAutoProxy.xml");

UserService userService = context.getBean(UserService.class);
OrderService orderService = context.getBean(OrderService.class);

userService.createUser("Tom", "Cruise", 55);
userService.queryUser();

orderService.createOrder("Leo", "随意买点什么");
orderService.queryOrder("Leo");
}
}

输出:


预备履行办法: createUser, 参数列表:[Tom, Cruise, 55]
queryUser办法回来:User{firstName='test', lastName='test', age=20, address='null'}
预备履行办法: createOrder, 参数列表:[Leo, 随意买点什么]
queryOrder办法回来:Order{username='test', product='test'}

从输出成果,咱们能够看到:

LogArgsAdvice 效果于 UserService#createUser(…) 和 OrderService#createOrder(…) 两个办法;

LogResultAdvice 效果于 UserService#queryUser() 和 OrderService#queryOrder(…) 两个办法;

下面的代码剖析中,咱们将依据这个简略的比如来介绍。

IOC 容器办理 AOP 实例

本节介绍 Spring AOP 是怎样效果于 IOC 容器中的 bean 的。

Spring AOP 的运用介绍 那篇文章现已介绍过 DefaultAdvisorAutoProxyCreator 类了,它能完结主动将一切的 advisor 收效。

咱们来追寻下 DefaultAdvisorAutoProxyCreator 类,看看它是怎样一步步完结的动态署理。然后在这个基础上,咱们再简略追寻下 @AspectJ 装备办法下的源码完结。

首要,先看下 DefaultAdvisorAutoProxyCreator 的承继结构:

咱们能够发现,DefaultAdvisorAutoProxyCreator 终究居然是一个 BeanPostProcessor,在 Spring IOC 源码剖析的时分说过,BeanPostProcessor 的两个办法,别离在 init-method 的前后得到履行。

public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

这儿再贴一下 IOC 的源码,咱们回忆一下:

// AbstractAutowireCapableBeanFactory

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 1. 创立实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
...

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 2. 装载特点
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 3. 初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
...
}

在上面第 3 步 initializeBean(...) 办法中会调用 BeanPostProcessor 中的办法,如下:


protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 1. 履行每一个 BeanPostProcessor 的 postProcessBeforeInitialization 办法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// 调用 bean 装备中的 init-method="xxx"
invokeInitMethods(beanName, wrappedBean, mbd);
}
...
if (mbd == null || !mbd.isSynthetic()) {
// 咱们重视的重点是这儿!!!
// 2. 履行每一个 BeanPostProcessor 的 postProcessAfterInitialization 办法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

也便是说,Spring AOP 会在 IOC 容器创立 bean 实例的终究对 bean 进行处理。其实便是在这一步进行署理增强。

咱们回过头来,DefaultAdvisorAutoProxyCreator 的承继结构中,postProcessAfterInitialization() 办法在其父类 AbstractAutoProxyCreator 这一层被覆写了:

// AbstractAutoProxyCreator


@Override
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;
}

持续往里看 wrapIfNecessary(...) 办法,这个办法将回来署理类(假如需求的话):


protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && 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
// 关于本文的比如,"userServiceImpl" 和 "OrderServiceImpl" 这两个 bean 创立进程中,
// 到这边的时分都会回来两个 advisor
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;
}

这儿有两个点提一下:

getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null),这个办法将得到一切的可用于阻拦当时 bean 的 advisor、advice、interceptor。

另一个便是 TargetSource 这个概念,它用于封装实在完结类的信息,上面用了 SingletonTargetSource 这个完结类,其实咱们这儿也不太需求关怀这个,知道有这么回事就能够了。

咱们持续往下看 createProxy(…) 办法:


// 留意看这个办法的几个参数,
// 第三个参数携带了一切的 advisors
// 第四个参数 targetSource 携带了实在完结的信息
protected Object createProxy(
Class

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

// 创立 ProxyFactory 实例
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

// 在 schema-based 的装备办法中,咱们介绍过,假如期望运用 CGLIB 来署理接口,能够装备
// proxy-target-class="true",这样不论有没有接口,都运用 CGLIB 来生成署理:
// ......
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 点进去略微看一下代码就知道了,首要就两句:
// 1. 有接口的,调用一次或屡次:proxyFactory.addInterface(ifc);
// 2. 没有接口的,调用:proxyFactory.setProxyTargetClass(true);
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

// 这个办法会回来匹配了当时 bean 的 advisors 数组
// 关于本文的比如,"userServiceImpl" 和 "OrderServiceImpl" 到这边的时分都会回来两个 advisor
// 留意:假如 specificInterceptors 中有 advice 和 interceptor,它们也会被包装成 advisor,进去看下源码就清楚了
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 的实例,然后 set 了一大堆内容,剩余的作业就都是这个 ProxyFactory 实例的了,经过这个实例来创立署理: getProxy(classLoader)。

ProxyFactory 详解

依据上面的源码,咱们走到了 ProxyFactory 这个类了,咱们到这个类来一看终究。

顺着上面的路子,咱们首要到 ProxyFactory#getProxy(classLoader) 办法:


public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}

该办法首要经过 createAopProxy() 创立一个 AopProxy 的实例:


protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

创立 AopProxy 之前,咱们需求一个 AopProxyFactory 实例,然后看 ProxyCreatorSupport 的结构办法:


public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}

这样就将咱们导到 DefaultAopProxyFactory 这个类了,咱们看它的 createAopProxy(…) 办法:


public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// (我也没用过这个optimize,默许false) || (proxy-target-class=true) || (没有接口)
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class
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)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
// 假如有接口,会跑到这个分支
return new JdkDynamicAopProxy(config);
}
}
// 判别是否有完结自界说的接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}

}

到这儿,咱们知道 createAopProxy 办法有或许回来 JdkDynamicAopProxy 实例,也有或许回来 ObjenesisCglibAopProxy 实例,这儿总结一下:

假如被署理的方针类完结了一个或多个自界说的接口,那么就会运用 JDK 动态署理,假如没有完结任何接口,会运用 CGLIB 完结署理,假如设置了 proxy-target-class="true",那么都会运用 CGLIB。

JDK 动态署理依据接口,所以只要接口中的办法会被增强,而 CGLIB 依据类承继,需求留意便是假如办法运用了 final 润饰,或者是 private 办法,是不能被增强的。

有了 AopProxy 实例今后,咱们就回到这个办法了:


public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}

咱们别离来看下两个 AopProxy 完结类的 getProxy(classLoader) 完结。

JdkDynamicAopProxy 类的源码比较简略,一共两百多行,


@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

java.lang.reflect.Proxy.newProxyInstance(…) 办法需求三个参数,第一个是 ClassLoader国王的演讲-Spring AOP 源码解析,第二个参数代表需求完结哪些接口,第三个参数最重要,是 InvocationHandler 实例,咱们看到这儿传了 this,由于 JdkDynamicAopProxy 自身完结了 InvocationHandler 接口。

InvocationHandler 只要一个办法,当生成的署理类对外供给服务的时分,都会导到这个办法中:


public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}

下面来看看 JdkDynamicAopProxy 对其的完结:


@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Class
Object target = null;

try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
// 署理的 equals 办法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
// 署理的 hashCode 办法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
//
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

// 假如设置了 exposeProxy,那么将 proxy 放到 ThreadLocal 中
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}

// Get the interception chain for this method.
// 创立一个 chain,包括一切要履行的 advice
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
// chain 是空的,阐明不需求被增强,这种状况很简略
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
// 履行办法,得到回来值
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}

// Massage return value if necessary.
Class
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

上面就片言只语说了一下,感兴趣的读者自己去深化探究下,不是很难。简略地说,便是在履行每个办法的时分,判别下该办法是否需求被一次或屡次增强(履行一个或多个 advice)。

说完了 JDK 动态署理 JdkDynamicAopProxy#getProxy(classLoader),咱们再来瞄一眼 CGLIB 的署理完结 ObjenesisCglibAopProxy#getProxy(classLoader)。

ObjenesisCglibAopProxy 承继了 CglibAopProxy,而 CglibAopProxy 承继了 AopProxy。

ObjenesisCglibAopProxy 运用了 Objenesis 这个库,和 cglib 相同,咱们不需求在 maven 中进行依靠,由于 spring-core.jar 直接把它的源代码也搞过来了。

经过 CGLIB 生成署理的代码量有点大,咱们就不进行深化剖析了,咱们看下大体的骨架。它的 getProxy(classLoader) 办法在父类 CglibAopProxy 类中:

// CglibAopProxy#getProxy(classLoader)


@Override
public Object getP国王的演讲-Spring AOP 源码解析roxy(ClassLoader classLoader) {
...
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

Callback[] callbacks = getCallbacks(rootClass);
Class
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
...
}
catch (IllegalArgumentException ex) {
...
}
catch (Throwable ex) {
...
}
}

CGLIB 生成署理的中心类是 Enhancer 类,这儿就不打开说了。

依据注解的 Spring AOP 源码剖析

上面咱们蜻蜓点水地介绍了运用 DefaultAdvisorAutoProxyCreator 来完结 Spring AOP 的源码,这儿,咱们也相同蜻蜓点水地来看下 @AspectJ 的完结原理。

咱们之前说过,敞开 @AspectJ 的两种办法,一个是 ,一个是 @EnableAspectJAutoProxy,它们的原理是相同的,都是经过注册一个 bean 来完结的。

解析 需求用到 AopNamespaceHandler:

然后到类 AspectJAutoProxyBeanDefinitionParser:


class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {

@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}
...
}

进去 registerAspectJAnnotationAutoProxyCreatorIfNecessary(...) 办法:


public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {

BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}

再进去 AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(...):


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {

return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

终究咱们看到,Spring 注册了一个 AnnotationAwareAspectJAutoProxyCreator 的 bean,beanName 为:"org.springframework.aop.config.internalAutoProxyCreator"。

咱们看下 AnnotationAwareAspectJAutoProxyCreator 的承继结构:

和前面介绍的 DefaultAdvisorAutoProxyCreator 相同,它也是一个 BeanPostProcessor,剩余的咱们就不说了,它和它的父类 AspectJAwareAdvisorAutoProxyCreator 都不杂乱。

闲谈 InstantiationAwareBeanPostProcessor

为什么要说这个呢?由于我发现,许多人都认为 Spring AOP 是经过这个接口来效果于 bean 生成署理的。


public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

Object postProcessBeforeInstantiation(Class

boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

}

它和 BeanPostProcessor 的办法十分类似,而且它还承继了 BeanPostProcessor。

不细心看还真的欠好区别,下面是 BeanPostProcessor 中的两个办法:


Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

发现没有,InstantiationAware国王的演讲-Spring AOP 源码解析BeanPostProcessor 是 Instantiation,BeanPostProcessor 是 Initialization,它代表的是 bean 在实例化完结而且特点注入完结,在履行 init-method 的前后进行效果的。

而 InstantiationAwareBeanPostProcessor 的履行时机要前面一些,咱们需求翻下 IOC 的源码:


// AbstractAutowireCapableBeanFactory 447行
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
...
try {
// 让 InstantiationAwareBeanPostProcessor 在这一步有时机回来署理
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
// BeanPostProcessor 是在这儿面实例化后才干得到履行
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
...
return beanInstance;
}

点进去看 resolveBeforeInstantiation(beanName, mbdToUse) 办法,然后就会导到 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 办法,关于咱们剖析的 AOP 来说,该办法的完结在 AbstractAutoProxyCreator 类中:


@Override
public Object postProcessBeforeInstantiation(Class
...
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;
}

咱们能够看到,这儿也有创立署理的逻辑,以至于许多人会搞错。的确,这儿是有或许创立署理的,但条件是关于相应的 bean 咱们有自界说的 TargetSource 完结,进到 getCustomTargetSource(...) 办法就清楚了,咱们需求装备一个 customTargetSourceCreators,它是一个 TargetSourceCreator 数组。

这儿就不再打开说 Targe国王的演讲-Spring AOP 源码解析tSource 了,请参阅 Spring Reference 中的 Using TargetSources。

小结

本文真的是蜻蜓点水,和我之前写的文章有很大的不同,期望读者不会厌弃。

不过假如读者有看过之前的 Spring IOC 源码剖析和 Spring AOP 运用介绍 这两篇文章的话,经过看本文应该能对 Spring AOP 的源码完结有比较好的了解了。

本文说细节说得比较少,假如你在看源码的时分碰到不明白的,欢迎在谈论区留言与咱们进行沟通。

(全文完)