Back to the home page

I have written IOC source code analysis before, that article is really a bit long, need some patience after reading. Many readers hope to write a Spring AOP source analysis article, so that readers will have a deep understanding of Spring after reading IOC + AOP. Today is finally written, may be many readers no longer wait, but mainly for the latecomers.

Unlike the IOC source analysis article, this article will not go into the specifics of every line of Spring AOP source code. It will be aimed at readers who already know what Spring IOC source code is, because Spring AOP ultimately relies on the IOC container to manage it.

1. Understand the source code of the IOC container first. AOP depends on the IOC container to manage. 2. Read through this introduction to the use of Spring AOP and understand the various uses before you can “guess” how it should be implemented.

Spring AOP source code is not simple, because it is much, so the best way to read the source code is to find a branch and track it down. This article is positioned as a cursory glance, look at the general, not specific to every detail.

preface

In this section, we’ll start by “guessing” how Spring implements AOP.

In the Spring container, the objects we are facing are bean instances. What are beans? Spring will produce the appropriate bean instance for us based on the information in the BeanDefinition. When we need to use beans, we use the IOC container’s getBean(…) The getBean(…) method gets the bean instance from the container, but in most scenarios, we use dependency injection, so we rarely call getBean(…) manually. Methods.

The principle of Spring AOP is very simple, dynamic proxy, unlike AspectJ, which directly changes your bytecode.

The proxy pattern is simple: interface + real implementation class + proxy class, where both the real implementation class and the proxy class implement the interface and use the proxy class when instantiating. So what Spring AOP needs to do is generate such a proxy class and then replace the real implementation class to provide services externally.

What about the substitution process? It’s easy to implement in the Spring IOC container, in getBean(…) Spring uses JDK Proxy or CGLIB to dynamically generate an instance of the Proxy class.

GetBean (…). Methods are used to find or instantiate beans in the container, which is why Spring AOP can only work on beans in the Spring container. Spring AOP can’t do anything about objects that aren’t managed using the IOC container.

The debugging code used in this article

A good way to read the source code is to run the code to debug, because looking at it line by line is boring, and it’s hard to avoid missing something.

Now, let’s prepare some simple debugging code.

First, define two Service interfaces:

// 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();
}
Copy the code

Then, an interface implementation class is provided:

// 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; }}Copy the code

Write two pieces of Advice:

public class LogArgsAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable {system.out.println (" Prepare to execute method: "+ method.getName() + "," + arrays.toString (args)); }}Copy the code
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); }}Copy the code

Configure it:

Let’s review the configuration Advisor approach described in the previous article.

Each Advisor holds an advice instance internally, the Advisor is responsible for matching, and the internal advice is responsible for implementing interception processing. Configuration after each advisor configuration DefaultAdvisorAutoProxyCreator makes all the advisor configuration automatically take effect.

Activation:

Public class SpringAopSourceApplication {public static void main (String [] args) {/ / start the Spring IOC container 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", "buy anything "); orderService.queryOrder("Leo"); }}Copy the code

Output:

Preparation execution method: CreateUser: [Tom, Cruise, 55] queryUser User{firstName='test', lastName='test', age=20, address='null'} QueryOrder {username='test', product='test'}Copy the code

LogArgsAdvice applies to UserService#createUser(…) And OrderService# createOrder (…). Two methods;

LogResultAdvice works on UserService#queryUser() and OrderService#queryOrder(…) Two methods;

The following code analysis will be based on this simple example.

The IOC container manages AOP instances

This section describes how Spring AOP works with beans in an IOC container.

The use of Spring AOP is introduced The article has introduced DefaultAdvisorAutoProxyCreator class, it can realize automatic will take effect all the advisor.

We to track down the DefaultAdvisorAutoProxyCreator class, look at how it step by step to realize the dynamic proxy. From there, let’s briefly trace the source code implementation in the @AspectJ configuration.

First, look at the inheritance structure of a DefaultAdvisorAutoProxyCreator:

We can find that DefaultAdvisorAutoProxyCreator finally was a BeanPostProcessor, said at the time of Spring IOC source code analysis, BeanPostProcessor of two methods, Are executed before and after init-method.

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

Here is the IOC source code again, let’s review:

// 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. Load the property populateBean(beanName, MBD, instanceWrapper); if (exposedObject ! = null) {// 3. Initialize exposedObject = initializeBean(beanName, exposedObject, MBD); }}... }Copy the code

In step 3 above, initializeBean(…) Method calls the BeanPostProcessor method as follows:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { ... Object wrappedBean = bean; if (mbd == null || ! MBD. IsSynthetic ()) {/ / 1. Perform each BeanPostProcessor wrappedBean = postProcessBeforeInitialization method applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); }... if (mbd == null || ! Mbd.issynthetic ()) {// Our focus is here!! / / 2. Perform each BeanPostProcessor wrappedBean = postProcessAfterInitialization method applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }Copy the code

That is, Spring AOP will process the bean at the end of the bean instance creation in the IOC container. This is where agent enhancement takes place.

We looked back and DefaultAdvisorAutoProxyCreator inheritance structure, postProcessAfterInitialization () method in its parent class AbstractAutoProxyCreator this layer covering wrote:

// 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; }Copy the code

Keep reading wrapIfNecessary(…) Method, which returns the proxy class (if needed) :

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; } // Return all advisors, advice, interceptor that match the current bean. Both "userServiceImpl" and "OrderServiceImpl" return two Advisor Object[] specificInterceptors = when they arrive here getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors ! = DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // Create proxy... Creating an agent... Creating an agent... 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; }Copy the code

Here are two points to mention:

GetAdvicesAndAdvisorsForBean (bean. GetClass (), beanName, null), this method will get all can be used to intercept the current bean advisor, advice, interceptor.

Another is the concept of TargetSource, which is used to encapsulate the real implementation of the information, the above use of the SingletonTargetSource implementation class, in fact, we do not need to care about this, know that there is such a thing can be.

Let’s move on to createProxy(…) Methods:

// The third parameter carries all the advisors. // The fourth parameter, targetSource, carries the actual implementation information. > 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); // Proxy-target-class ="true"; // Proxy-target-class ="true";  // <aop:config proxy-target-class="true">...... </aop:config> if (! proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else {// 1. Interface, call one or more: proxyFactory. AddInterface (ifc); / / 2. No interface, call: proxyFactory. SetProxyTargetClass (true); evaluateProxyInterfaces(beanClass, proxyFactory); }} // This method returns the advisors array that matches the current bean. // For the example in this article, "userServiceImpl" and "OrderServiceImpl" return two Advisors. // Note: If we have advice and Interceptor in specificInterceptors, they will also be wrapped as advisors, 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()); }Copy the code

As you can see, this method basically creates an instance of ProxyFactory internally, and then sets a bunch of content. The rest of the work is done by creating the proxy from the instance: getProxy(classLoader).

ProxyFactory,

According to the above source code, we went to the ProxyFactory class, we go to this class to see what it is.

ProxyFactory#getProxy(classLoader)

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

This method starts by creating an instance of AopProxy with createAopProxy() :

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

To create AopProxy, we need an instance of AopProxyFactory and look at the constructor of ProxyCreatorSupport:

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

This leads us to DefaultAopProxyFactory, whose createAopProxy(…) Methods:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // (I haven't used optimize either, The default false) | | (proxy - target - class = true) | | (no interface) 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 the class you want to delegate is an interface, you can also use JDK dynamic proxy. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); Return new JdkDynamicAopProxy(config);} else {// If there is an interface, it will go to the branch. }} / / determine whether have implement custom interface private Boolean hasNoUserSuppliedProxyInterfaces (AdvisedSupport config) {Class <? >[] ifcs = config.getProxiedInterfaces(); return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]))); }}Copy the code

CreateAopProxy may return JdkDynamicAopProxy or ObjenesisCglibAopProxy.

JDK dynamic proxies are used if the propped target class implements one or more custom interfaces, CGLIB is used if no interfaces are implemented, and proxy-target-class=”true” is used.

JDK dynamic proxies are based on interfaces, so only methods in interfaces are enhanced, whereas CGLIB is based on class inheritance. It is important to note that methods that use final or private methods cannot be enhanced.

Now that we have the AopProxy instance, we return to this method:

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

Let’s look at the getProxy(classLoader) implementation of the two AopProxy implementation classes respectively.

JdkDynamicAopProxy class source code is relatively simple, a total of more than two hundred lines,

@Override public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<? >[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }Copy the code

Java. Lang. Reflect the Proxy newProxyInstance (…). The method takes three arguments, the first is ClassLoader, the second argument is what interface needs to be implemented, and the third argument, most important, is the InvocationHandler instance, and we see that we passed this, Because JdkDynamicAopProxy itself implements the InvocationHandler interface.

The InvocationHandler has only one method, which is generated when the proxy class provides a service to the outside world:

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

Let’s take a look at the JdkDynamicAopProxy implementation:

@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<? > targetClass = null; Object target = null; try { if (! this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method // The equals method of the proxy returns equals(args[0]); } else if (! this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method // The agent's hashCode method returns 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; // If exposeProxy is set, 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. Contains all the advice to List < Object > 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 Considerations or fancy proxying. // Chain is empty, indicating no need to be augmented, This kind of situation is simple Object [] argsToUse = AopProxyUtils. AdaptArgumentsIfNecessary (method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // We need to create a method invocation... / / execution method, we get the return value invocation = new ReflectiveMethodInvocation (proxy, target, method and the args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed(); } // Massage return value if necessary. Class<? > returnType = method.getReturnType(); 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); }}}Copy the code

The above said a few words, interested readers to explore their own in-depth, not very difficult. Simply put, as each method is executed, determine whether the method needs to be enhanced one or more times (perform one or more advice).

ObjenesisCglibAopProxy#getProxy(classLoader) ¶

ObjenesisCglibAopProxy inherits CglibAopProxy, and CglibAopProxy inherits AopProxy.

ObjenesisCglibAopProxy uses the Objenesis library. Like Cglib, we don’t need to rely on maven because spring-core-jar comes directly from its source code.

The amount of code required to generate a proxy from CGLIB is a bit large, so we won’t go into the details, but take a look at the skeleton. Its getProxy(classLoader) method is in the parent CglibAopProxy class:

// CglibAopProxy#getProxy(classLoader)

@Override public Object getProxy(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<? >[] types = new Class<? >[callbacks.length]; 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) { ... }}Copy the code

The core class of the CGLIB generation agent is the Enhancer class, which will not be expanded here.

Annotation-based Spring AOP source code analysis

We tour introduced above using DefaultAdvisorAutoProxyCreator to realize Spring AOP source, here, we also tour to see the realization of the @aspectj principle.

As mentioned earlier, there are two ways to enable @AspectJ: < AOP: AspectJ-AutoProxy /> and @enableAspectJAutoProxy. They work the same way by registering a bean.

To parse
, use AopNamespaceHandler:

And then to the class AspectJAutoProxyBeanDefinitionParser:

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser { @Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; }... }Copy the code

In registerAspectJAnnotationAutoProxyCreatorIfNecessary (…). Methods:

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

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

Again in AopConfigUtils# registerAspectJAnnotationAutoProxyCreatorIfNecessary (…). :

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

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

Finally, we see the Spring registered a AnnotationAwareAspectJAutoProxyCreator bean, beanName as follows: “Org. Springframework. Aop. Config. InternalAutoProxyCreator”.

We see AnnotationAwareAspectJAutoProxyCreator inheritance structure:

And the DefaultAdvisorAutoProxyCreator before it, it is also a BeanPostProcessor, the rest of us just don’t say, It and its parent class AspectJAwareAdvisorAutoProxyCreator are not complicated.

Chatting InstantiationAwareBeanPostProcessor

Why do you say that? Because I’ve noticed that a lot of people think that Spring AOP works with bean generation proxies through this interface.

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { Object postProcessBeforeInstantiation(Class<? > beanClass, String beanName) throws BeansException; boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException; }Copy the code

It is very similar to and inherits BeanPostProcessor’s methods.

It’s hard to tell apart without looking closely, but here are two methods in BeanPostProcessor:

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

Is found, no InstantiationAwareBeanPostProcessor Instantiation, BeanPostProcessor is Initialization, it represents the bean is instantiated completed and property injection is completed, Before and after init-method is executed.

And InstantiationAwareBeanPostProcessor execution time to some front, we need to turn down the IOC’s source code:

/ / AbstractAutowireCapableBeanFactory 447 lines of protected Object createBean (String beanName, RootBeanDefinition MBD, Object[] args) throws BeanCreationException { ... Try {/ / let InstantiationAwareBeanPostProcessor agent in this step the chance to return the Object bean = resolveBeforeInstantiation (beanName mbdToUse);  if (bean ! = null) { return bean; Object beanInstance = doCreateBean(beanName, mbdToUse, args); . return beanInstance; }Copy the code

Point into the resolveBeforeInstantiation (beanName mbdToUse) method, And then will lead to InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation method, for our analysis of AOP, This method is implemented in the AbstractautoxyCreator class:

@Override public Object postProcessBeforeInstantiation(Class<? > beanClass, String beanName) throws BeansException { ... 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; }Copy the code

As you can see, there is also the logic to create proxies that many people get wrong. Indeed, it is possible to create a proxy here, but only if we have a custom TargetSource implementation for the corresponding bean, going to getCustomTargetSource(…). The method is clear, we need to configure a customTargetSourceCreators, it is a TargetSourceCreator array.

TargetSource is not expanded here, refer to Using TargetSources in Spring Reference.

summary

This article is really a quick look, and I wrote before the article is very different, I hope readers do not mind.

However, if the reader has seen the previous Spring IOC source analysis and Spring AOP introduction to the use of these two articles, through reading this article should be able to Spring AOP source implementation have a better understanding.

This article said that the details are less, if you look at the source encountered do not understand, welcome to the comment area and everyone to exchange messages.

(Full text)