* * Second, the design and implementation of AOP
1. Dynamic agent characteristics of the JVM * *
In the spring AOP implementation, the core technology used is the dynamic proxy, and this dynamic agent is actually a feature of the JDK. With the dynamic proxy feature of the JDK, proxy objects can be created for any Java object, and for specific use, this feature is done through the Java Reflection API. Before this, briefly review the proxy mode, its static class diagram is as follows:
We can see that there is a realsubject, this object is the target object, and in the design of the proxy mode, we will design an interface and a target object consistent proxy object proxy, they all implement the interface subject request method. In this case, the request call to the target object is often intercepted by the proxy object "troubled Waters". Through this interception, the target object of the method of operation of the cushion.
In the invocation of proxy, if the client calls the request method of proxy, the request method of the target object is called, and a series of processing is called before and after invoking the request method of the target object, and this series of processing is equivalent to the target object is transparent, The target object can have no knowledge of these processes, which is the proxy mode.
We know that this proxy pattern has been implemented in the JDK, and it is only necessary to use this feature directly when designing an application based on a Java virtual machine. Specifically, you can see the proxy object in Java's reflection package, which, after the object is generated, acts like a proxy object in proxy mode. When used, it is also necessary to design a callback method for the proxy object, which serves as an action that requires additional processing as a proxy. This callback method, if implemented in the JDK, requires implementing the Invocationhandler interface shown below:
publicinterface InvocationHandler{ publicinvoke(Object proxy,Method method,Object[] args) throws Throwable;}
As for the Invoke method and the proxy hook hook, familiar with the proxy usage of the reader know that As long as the implementation by calling the Proxy.newinstance method to generate a specific proxy object, the Invocationhandler set to the parameters inside it, the rest of the Java Virtual machine to complete.
2. Design analysis of Spring AOP
Based on dynamic agent technology, Spring AOP designs a series of crosscutting implementations of AOP, such as forward notification, return notification, exception notification, and so on. At the same time SPRINGAOP also provides a series of pointcut to match the entry point, you can use the existing pointcuts to design cross-sectional, can also extend the relevant Pointcut method to cut into demand.
In spring AOP, while it is only necessary to configure the relevant bean definitions for the users of AOP, careful analysis of the spring AOP internal design can be seen in order for AOP to work by completing a series of processes, such as the need to establish a proxy object for the target object. This proxy object can be done by using the JDK's proxy, or by a third-party class builder, Cglib. Then, you need to start the proxy object interceptor to complete a variety of cross-sectional weaving, this series of weaving design is achieved through a series of adapter. Through the design of adapter, the cross-sectional design of AOP and the proxy mode can be organically combined to realize the various weaving methods defined in AOP.
3. Application Scenarios of Spring AOP
SPRINGAOP abstracts the functionality of multiple modules across applications, and is flexibly compiled into modules through the use of simple AOP, such as the ability to implement logging in applications through AOP. On the other hand, within spring, some support modules are also implemented through spring AOP, such as the transaction that will be described later. The following is an example of the implementation of Proxyfactorybean, together with you to understand the specific design and implementation of Spring AOP
* * Third, establish Aopproxy proxy object
1. Design Principle * *
One of the main parts of spring's AOP module is the generation of proxy objects, and for spring applications you can see that this is done by configuring and invoking spring's proxyfactorybean. In Proxyfactorybean, the generation process of the primary proxy object is encapsulated. In this process, you can use the JDK proxy and cglib two ways.
With the Proxyfactorybean design as the center, you can see the inheritance relationship of the related classes:
2, Configuration Proxyfactorybean
We began to enter the implementation of Spring AOP, in the analysis of the implementation of Spring AOP principle, mainly in the implementation of Proxyfactorybean as an example and the basic clues to the implementation of the analysis. This is because Proxyfactorybean is the underlying approach to creating an AOP application in the spring IOC environment and the most flexible approach, with which spring has completed the encapsulation of AOP using. Taking Proxyfactorybean's implementation as the portal, layered in-depth, is a learning path that helps us quickly understand the implementation of Spring AOP.
Before understanding the implementation of Proxyfactorybean, a brief introduction to the configuration and use of the next Proxyfactorybean, in the XML-based configuration of spring beans, often requires a series of configuration subsidies to use Proxyfactorybean and AOP.
1) define the notifier advisor used, and this notifier should be defined as a bean. The implementation of this notifier defines the facet behavior that needs to be enhanced for the target object, that is, the advice notification.
2) define Proxyfactorybean, define him as another bean, and he is the main class that encapsulates the functionality of AOP.
3) Define the target property, the bean that is injected as the target property, which is an object that needs to be augmented with the slice application in the AOP notifier, which is the base object mentioned earlier.
With these configurations, you can use Proxyfactorybean to complete the basic functionality of AOP, such as:
<bean id="Testadvisor" class="Com.jader.TestAdvisor "/> <bean id= "testaop" class=" Org.springframework.aop.ProxyFactoryBean "> < property name="Proxyinterfaces"> <value>Com.jader.AbcInterface</value> </Property > < property name="Interceptornames"> <list> <value>Testadvisor</value> </list> </Property ></Bean>
With these configuration information in hand, you can take a look at how these AOP are implemented, that is, how the slice application works with the target object through Proxyfactorybean, which is analyzed in detail below.
3, Proxyfactorybean generate Aopproxy proxy object
in the use of spring AOP, we already know that You can configure target objects and facet behavior through Proxyfactorybean. This proxyfactorybean is a factorybean. In Proxyfactorybean, the Interceptornames attribute is configured to configure the Notifier advisor that is already defined. Although the name is Interceptornames, it is actually a place for the AOP application to configure the notifier. In Proxyfactorybean, you need to generate proxy proxy objects for the target object to prepare for the cross-sectional weaving of AOP. The AOP implementations of the
Proxyfactorybean need to rely on the proxy features provided by the JDK or cglib. Getting objects from Factorybean is done with the GetObject method as an entry, and the GetObject method in Proxyfactorybean implementation is the interface that Factorybean needs to implement. For Proxyfactorybean, the enhanced processing that needs to be added to target objects is encapsulated by the GetObject method. These enhancements are provided for the implementation of the AOP functionality. The GetObject method first initializes the notifier chain, which encapsulates a series of interceptors that are read from the configuration and ready for the proxy object generation. When generating proxy objects, because spring has singleton types and prototype similar to these two different beans, a distinction is made to the generation of proxy objects. The code for
GetObject is as follows:
/** * Return a proxy. Invoked when clients obtain beans from the This factory bean. * Create An instance of the AOP proxies to being returned by this factory. * The instance is cached for a singleton, and create on each call to * {@code getObject ()} for a proxy. * @return a fresh AOP proxy reflecting the current state of this factory */ PublicObjectGetObject()throwsbeansexception {//Initialize the notifier chain hereInitializeadvisorchain ();//Here the types of singleton and prototype are differentiated and the corresponding proxies are generated if(Issingleton ()) {returnGetsingletoninstance (); }Else{if( This. TargetName = =NULL) {Logger.warn ("Using Non-singleton proxies with singleton targets is often undesirable."+"Enable prototype proxies by setting, the ' TargetName ' property."); }returnNewprototypeinstance (); } }
Configuring the Advisor chain for proxy proxies is implemented in the Initializeadvisorchain method. This initialization process has a flag bit advisorchaininitialized, which is used to indicate whether the notifier has been initialized. If it is initialized, it will be initialized and returned directly. It also says that this initialization work happens when the application first passes through the Proxyfactorybean to get the proxy object. After this initialization, and then read all the notifications that appear in the configuration, the process of getting the notifier is relatively simple, giving the name of the notifier to the container's Getbean method, which is accomplished by a callback to the IOC container implementation. The notifier obtained from the IOC container is then added to the interceptor chain, and this action is implemented by the Addadvisoronchaincreation method.
The following is a look at the initialization of the advisor configuration chain:
/** * Create the Advisor (Interceptor) chain. Aadvisors that was sourced * from a beanfactory would be refreshed each time a new prototype instance * is added. Interceptors added programmatically through the factory API * is unaffected by such changes. */ Private synchronized void Initializeadvisorchain()throwsAopconfigexception, Beansexception {if( This. advisorchaininitialized) {return; }if(! Objectutils.isempty ( This. Interceptornames)) {if( This. Beanfactory = =NULL) {Throw NewIllegalStateException ("No beanfactory available anymore (probably due to serialization)"+"-Cannot resolve interceptor names"+ Arrays.aslist ( This. interceptornames)); }//Globals can ' t be last unless we specified a targetsource using the property ... if( This. interceptornames[ This. Interceptornames.length-1].endswith (Global_suffix) && This. TargetName = =NULL&& This. Targetsource = = Empty_target_source) {Throw NewAopconfigexception ("Target required after Globals"); }//Materialize interceptor chain from bean names. //Here is the call to add the advisor chain, which is configured by the Interceptornames property for(String name: This. interceptornames) {if(Logger.istraceenabled ()) {Logger.trace ("Configuring advisor or advice '"+ name +"'"); }if(Name.endswith (Global_suffix)) {if(! ( This. beanfactoryinstanceofListablebeanfactory)) {Throw NewAopconfigexception ("Can only use global advisors or interceptors with a listablebeanfactory"); } addglobaladvisor ((listablebeanfactory) This. Beanfactory, Name.substring (0, Name.length ()-global_suffix.length ())); }Else{//If We get here, we need to add a named Interceptor. //We must check if it ' s a singleton or prototype. //If the program is called here, you need to join the named Interceptor advice, and you need to check whether the bean is singleton or prototype typeObject advice;if( This. Singleton | | This. Beanfactory.issingleton (name)) {//Add The real advisor/advice to the chain.Advice = This. Beanfactory.getbean (name); }Else{//It ' s a prototype Advice or Advisor:replace with a prototype. //Avoid Unnecessary creation of prototype Bean just for advisor chain initialization.Advice =NewPrototypeplaceholderadvisor (name); } addadvisoronchaincreation (advice, name); } } } This. advisorchaininitialized =true; }
To be Continued ...
Spring Technology Insider: The implementation principle of Spring AOP (II.)