Small:

  • The difference between pre-instantiation and post-instantiation is whether a constructor is inferred, which is necessary for instantiation.
  • Bean instantiation and initialization differ whether the Bean is populated with properties, which are initialized.
  • An AOP dynamic proxy for a Bean is created after initialization, but if the looping dependent Bean uses AOP. You need to create AOP ahead of time after instantiation and before initialization.

Introduction to AspectJ and AOP and their relationships?

What technology is AOP?

AOP breaks the system down into different concerns, or aspects — a wrapper around the code we originally wrote, doing some intercepting or enhancing before and after method execution to reduce code duplication. When we implement a proxy, the actual running instance is actually an instance of the generated proxy class.

AOP in Spring? (Contrast with AspectJ)

  • Spring 2.0 @AspectJ configuration: It feels most convenient to use annotations for configuration, and although it is called @aspectJ, it has nothing to do with AspectJ.
  • Ring AOP only works on beans in the Spring container. It is implemented using pure Java code and only works on Bean methods.
  • Spring AOP needs to rely on the IOC container for management.
  • Spring provides AspectJ support, but only with AspectJ pointcut parsing and matching.
  • Spring AOP is based on proxy implementations, which require proxy instances to be generated at container startup and add stack depth to method calls, making Spring AOP not as high-performance as AspectJ.
  • The spring source code only uses the annotations in AspectJRT-1.9.5.jar, but does not rely on its implementation.

What is AspectJ?

  • Compile time weaving: if class A uses AspectJ to add an attribute and class B uses it, the scenario needs to be weaving at Compile time otherwise class B cannot be compiled.
  • The part where we need to do the post-compile weaving is where the.class file is generated or the jar package is generated.
  • Load-time weaving: Weaving is the weaving that happens when classes are being loaded, and there are several common ways to do this.
    1. Custom class loaders do this, and this is probably the easiest way to load the woven class before it is loaded into the JVM, so that you can define the behavior at load time.
    2. The JVM startup specify AspectJ provide agent: – javaagent: XXX/XXX/aspectjweaver. Jar. Spring AOP is slower than AspectJ) because AspectJ does the weaving before the actual code runs, one could argue that it generates classes with no additional runtime overhead.

Advisor and Advice

-Chuck: I didn’t get Advice.

  1. Preadvice: MethodBeforeAdvice
  2. Afteradvice: AfterReturningAdvice
  3. Surround Advice: MethodInterceptor
  4. Exception Advice: ThrowsAdvice

When using Spring AOP to generate a proxy object, we can set the Advice for the proxy object. It just says “advice”, it doesn’t say where this “advice” can be used. Advisor, which indicates where an Advice(worker) can be applied, and “where” is the Pointcut.

Spring AOP source code parsing – thinking ideas

  1. Find all section classes
  2. Parse all advice and save it
  3. Create a dynamic proxy class
  4. When a proxied class’s method is called, all of its enhancers are found and the current method is enhanced

First, enter the process of parsing section:

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
Copy the code

Tracking the source to AnnotationAwareAspectJAutoProxyCreator can see, in the end, we have a look at his class diagram, found it implements two important interfaces, BeanPostProcessor and InstantiationAwareBeanPostProcessor.

First look at InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation method – > Object postProcessBeforeInstantiation (Class <? > beanClass, String beanName) (InstantiationAwareBeanPostProcessor)


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation


org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip


org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors


org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors


Find all methods of the aspect class that do not include the @pointcut annotation //2. Filter out methods that contain annotations @around, @before, @after, @afterreturning, @afterthrowing. Encapsulated in the List returned List classAdvisors = this. AdvisorFactory. GetAdvisors (factory);


List cachedAdvisors = this.Advisorscache. Get (aspectName);

Second, create proxies org. Springframework. Beans. Factory. Support. AbstractAutowireCapableBeanFactory# doCreateBean exposedObject = initializeBean(beanName, exposedObject, mbd);


// AOP after initialization

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);


Object current = processor.postProcessAfterInitialization(result, beanName);


1. Access to advisors:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean ! = null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); // earlyProxyReferences contains any pre-aop beans, // Note that earlyProxyReferences does not store the post-AOP proxy object BeanPostProcessor if (this.earlyProxyReferences.remove(cacheKey) ! AOP return wrapIfNecessary(bean, beanName, cacheKey) {// AOP return wrapIfNecessary(bean, beanName, cacheKey); }} // Why not return the proxy object? return bean; // } wrapIfNecessary(bean, beanName, cacheKey);Copy the code

// Get the advisors matched by the current beanClass

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 2. Match: Match according to the advisors and the current bean according to the pointcut expression to see if it matches. org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class<?>, Boolean) to get the PointCut org. Springframework. Aop. Support. AopUtils# canApply (org. Springframework. Aop PointCut, java.lang.Class<?>, Boolean) org. Springframework. Aop. ClassFilter# matches coarse sieve org. Springframework. Aop) IntroductionAwareMethodMatcher# matches Fine screenCopy the code

3. Create proxy: If the advisor matching the current Bean is found, the conditions for creating dynamic proxy are met:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // Save a proxy object of type this.proxytypes. put(cacheKey, proxy.getClass()); // Cglib must be used for proxy if (! ProxyFactory. IsProxyTargetClass ()) {/ / if not specified, If (shouldProxyTargetClass(shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); EvaluateProxyInterfaces (beanClass, proxyFactory); evaluateProxyInterfaces(beanClass, proxyFactory) // Check whether beanClass implements the interface}}Copy the code

JdkDynamicAopProxy creates a proxy object

  1. Gets the collection of interfaces that need to be implemented to generate the proxy object

A. get through ProxyFactory. AddInterface () to add the interface, if not through ProxyFactory addInterface add interface (), Then see ProxyFactory. SetTargetClass () set up by the targetClass is an interface, the interface is added to the result set b. Add SpringProxy, Advised, and DecoratingProxy interfaces to the result set. Once the collection to be proxied is determined, a Proxy object is generated using proxy.newProxyInstance ()

3. The invocation of the proxy class JdkDynamicAopProxy creates the proxy object execution process

  1. If by ProxyFactory setExposeProxy () the exposeProxy set to true, then set the proxy objects to a ThreadLocal (currentProxy).
  2. Gets the target set via ProxyFactory. If targetClass is set, target is null
  3. Find the matching Advisor from ProxyFactory based on the currently called method object, and package the Advisor as a MethodInterceptor return, resulting in a MethodInterceptor chain
  4. If chain is null, the current method corresponding to target is executed, or an error is reported if target is null
  5. If the chain is not empty, the MethodInterceptor in the chain is executed in turn

A. if the current MethodInterceptor is MethodBeforeAdviceInterceptor, then, an executive Advisor advice in before () method, and then execute the next MethodInterceptor b. If the current MethodInterceptor is AfterReturningAdviceInterceptor, then, first executed next MethodInterceptor, after get the return value, Then follow the advice afterReturning() method of ObjenesisCglibAopProxy to create a proxy object

  1. Create Enhancer
  2. Set the Enhancer superClass to the class of the object set via proxyfactory.settarget ()
  3. Set Enhancer interfaces by ProxyFactory. AddInterface () to add the interface, and SpringProxy, Advised interface
  4. Set up Callbacks for DynamicAdvisedInterceptor Enhancer
  5. Finally, create a proxy object through Enhancer

ObjenesisCglibAopProxy Specifies the execution process of the proxy object created

  1. In the implementation process mainly depends on DynamicAdvisedInterceptor implementation, execution of logic and JdkDynamicAopProxy is the same.