Before we begin our analysis of SpringAOP, let me ask you a question: what do you think are the most important aspects of AOP? I think there are several areas (welcome to point out any misunderstandings) : one is the configuration of AOP (configuration of interception rules), one is the creation of proxy objects, and one is a unified interception call process. Spring defines its own set of rules that integrate AspectJ syntax and are abstracted into Pointcut classes. To create proxy objects, SpringAOP defines a factory class, AopProxy, that supports both JDK dynamic proxies and CGlib dynamic proxies. The uniform interception call procedure uses the intercepting procedure defined in the AOP consortium: Advice—–>Interceptor——->MethodInterceptor. But SpringAOP expands on this foundation and forms its own set of architectures. Advice: classes defined in the SpringAOP consortium. Is an identifying interface. Notification type interface. It is also the parent of Interceptor and MethodInterceptor. Notification types have an interface to implement. Advisor: Associates Advice and Pointcut. Is a key class in SpringAOP. Up to match the join point and down to call the notification type. Unified interception invocation process. Advised: class associated with Advisor and TargetSource. It is also a key class in AOP. When AOP does method interception, it gets the interception call chain from it. A general relationship is as follows:

@Aspect
public class AopAdviceConfig {

    @Before("execution(* com.zkn.spring.learn.aop.program.service.. *. * (..) )")
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println(joinPoint.getThis());
        System.out.println("I am pre-notification...."); Public interface AspectJService {/** * test prenotification */ void beforeAdvice(); /** * void afterAdvice(); } public class AspectJServiceImpl implements AspectJService {@override public voidbeforeAdvice() {
        System.out.println("Test pre-notification, I am the first Service..."); } /** * test notification */ @override public voidafterAdvice() {
        System.out.println("Testing AspectJ postnotification..."); }}Copy the code

We programmatically implement an AOP interception function.

Public class AspectJProxyFactoryLearn {public static void main(String[] args) {// Manually create an instance of AspectJService aspectJService = new AspectJServiceImpl(); AspectJProxyFactory = new AspectJProxyFactory; / / add section and inform aspectJProxyFactory addAspect (AopAdviceConfig. Class); / / create a proxy object AspectJService proxyService = aspectJProxyFactory. GetProxy (); / / method calls proxyService. BeforeAdvice (); }}Copy the code

Let’s look at the output:

AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(aspectJService); Public AspectJProxyFactory(Object target) {assert. notNull(target,"Target object must not be null");
	setInterfaces(ClassUtils.getAllInterfaces(target));
	setTarget(target);
}
Copy the code

When we call the argument constructor of AspectJProxyFactory, it does these things: checks that the target object cannot be null, sets all the interfaces of the target object, and sets the target object. Get all the interfaces of class is by calling ClassUtils. GetAllInterfaces to obtain. This method can get all interfaces on a class, including interfaces on its parent class, but it cannot get the interface’s interface. Class A inherits from class B, class B implements interface C, and interface C inherits from interface D. If class A is passed in as A parameter, interface C can be retrieved, but not interface D.

//AdvisedSupport adds interface information public voidsetInterfaces(Class<? >... interfaces) { Assert.notNull(interfaces,"Interfaces must not be null"); List this.interfaces.clear();for(Class<? > ifc : interfaces) { addInterface(ifc); } //AdvisedSupport public void addInterface(Class<? > intf) { Assert.notNull(intf,"Interface must not be null"); // If the interface does not throw an exceptionif(! intf.isInterface()) { throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
		}
		if(! this.interfaces.contains(intf)) { this.interfaces.add(intf); adviceChanged(); } //ProxyCreatorSupport method protected voidadviceChanged() {
		super.adviceChanged();
		synchronized (this) {
			if(this.active) {// Send a notification to the Advised listener to notify the Advised changes // There is no default implementation in Springfor(AdvisedSupportListener listener : this.listeners) { listener.adviceChanged(this); }}}} // Protected void method in AdvisedSupportadviceChanged() {// Clear the cached method information. Clears methodCache //Map<MethodCacheKey, List<Object>> methodCache // why is this class name adviceChanged?? this.methodCache.clear(); }Copy the code

Setting the target Object

	public void setTarget(Object Target) {// SingletonTargetSource (SingletonTargetSource) {// SingletonTargetSource (SingletonTargetSource) is a singleton // The method in AdvisedSupport is calledsetThe TargetSource method is the one defined in the Advised methodsetTargetSource(new SingletonTargetSource(target));
	}
	// AdvisedSupport
	public void setTargetSource(TargetSource targetSource) { this.targetSource = (targetSource ! = null ? targetSource : EMPTY_TARGET_SOURCE); }Copy the code

The rest will be analyzed in the next chapter.