Spring AOP Implementation principle (ii) using spring AOP

Source: Internet
Author: User

As with AspectJ, spring AOP also needs to enhance the target class, which is to generate a new AOP proxy class; unlike AspectJ, Spring AOP No need to use any special

command to compile the Java source code, which takes the runtime to generate an AOP proxy in a way that dynamically and temporarily generates "proxy classes" in memory.


Spring allows the use of AspectJ Annotation for defining facets (Aspect), pointcuts (Pointcut), and enhanced Processing (Advice), which the spring framework recognizes and according to these

Annotation to generate an AOP proxy. Spring just uses the same annotations as AspectJ 5, but does not use the AspectJ compiler or the Loom (Weaver), and the underlying still uses

Is Spring AOP, which still generates an AOP proxy dynamically at run time, and does not rely on AspectJ compilers or weavers.


In short, Spring still uses the runtime to generate dynamic proxies to enhance the target object, so it does not need to add additional compilation, and does not require AspectJ weaving The AspectJ is supported by the device;

With compile-time enhancements, AspectJ needs to use its own compiler to compile Java files, and it needs a loom.


to enable spring support for @AspectJ configuration, and to ensure that the target Bean in the spring container is automatically enhanced by one or more aspects, the spring The configuration file is configured as follows

Fragment:

<?xml version= "1.0" encoding= "GBK"?> <beans  xmlns= "Http://www.springframework.org/schema/beans"         Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"         xmlns:aop= "Http://www.springframework.org/schema/aop "         xsi:schemalocation=" Http://www.springframework.org/schema/beans  http://www.springframework.org/ Schema/beans/spring-beans-3.0.xsd              HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP/  http Www.springframework.org/schema/aop/spring-aop-3.0.xsd >      <!--start @AspectJ Support-      <AOP: Aspectj-autoproxy/>  </beans>

of course, if we want to fully launch spring's 0 configuration feature, we also need to enable spring's 0 configuration support, allowing spring to automatically search for the Bean under the specified path class.


The so-called automatic enhancement, refers to the Spring will determine whether one or more aspects need to enhance the specified Bean, and automatically generate the corresponding proxy, so that the enhanced processing at the appropriate time

is called.


If you do not intend to use spring's XML Schema configuration, you should add the following fragment in the spring configuration file to enable @AspectJ support.

<!--start @AspectJ Support-  <bean class= " Org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator "/>


The annotationawareaspectjautoproxycreator in the above configuration file is a Bean post processor (beanpostprocessor) that the Bean post processor will will be in the container

The Bean generates an AOP proxy,


When @AspectJ support is enabled, as long as we configure a bean,spring with a @Aspect comment in the Spring container, the bean is automatically recognized and the Bean is used as a facet

Bean processing.


Configuring the Facet bean in the Spring container (that is, the bean with the @Aspect annotation) is no different from configuring a normal Bean , as is the case with the <bean.../> element, which supports

use Dependency injection to configure attribute values; If we launch spring's "0 Configuration" feature, you can let spring automatically search and load the specified path under the facet Bean.


Using a @Aspect to label a Java class, the Java class will act as a facet Bean, as shown in the following code snippet:

Use @Aspect to define a facet class @Aspect public class  Logaspect {      //define other contents of the class ...  }

Facet classes (classes decorated with @Aspect) can have methods, property definitions as well as other classes, and may include pointcuts, enhanced processing definitions.


When we use the @Aspect to decorate a Java class, Spring will not treat the bean as a component bean, so the post-processing bean responsible for auto-enhancement will skip the bean.

No enhancements will be made to the Bean.


There is no need to worry about using @Aspect defined aspect classes to be enhanced when the spring container detects that a bean class uses a @Aspect callout, and the spring capacitor does not

Class is enhanced.


The following will consider using Spring AOP to rewrite The example described earlier:


The following example uses a simple Chinese class to simulate a business logic component:

@Component public  class Chinese {     //SayHello () method that implements the person interface public    string SayHello (string name)  {
   system.out.println ("--SayHello method is being implemented--");         Returns a simple string return        name + "Hello, Spring AOP";     }     Define a Eat () method public    void Eat (String food) {         System.out.println ("I'm Eating:" + ")}  }

after providing the above Chinese class, next assume that you also need to add transaction control and logging for each method of the Chinese class above, consider using the Around,

Afterreturning two kinds of enhancement treatment.


First look at the Afterreturning enhanced processing code.

Define an aspect @Aspect public  class Afterreturningadvicetest {     //matches all classes under Org.crazyit.app.service.impl package,    // Execution of all methods as Pointcut    @AfterReturning (returning= "rvt", pointcut= "Execution (* org.crazyit.app.service.impl.*.* (..))")    public void log (object rvt) {         System.out.println ("Get Target method return value:" + rvt);         SYSTEM.OUT.PRINTLN ("Analog logging Function ...");}  }

The Aspect class above uses @Aspect adornments so that Spring treats it as a facet Bean. Where the bold code specified in the program will be called in the

All methods of all classes under the Org.crazyit.app.service.impl package are then woven into the log (Object rvt) method.

Then look at the Around Enhanced processing code:

Define an aspect @Aspect public  class Aroundadvicetest {     //matches all classes under Org.crazyit.app.service.impl package,    // Execution of all methods as Pointcut    @Around ("Execution (* org.crazyit.app.service.impl.*.* (..))")    Public Object Processtx (Proceedingjoinpoint JP) throws java.lang.Throwable {         System.out.println ("Impersonate the start transaction before executing the target method ...");         Executes the target method and saves the return value after the target method executes        object rvt = jp.proceed (new string[]{"changed parameter"});         SYSTEM.OUT.PRINTLN ("After executing the target method, simulating end transaction ...");         Return RVT + "What's new";     }  }

Similar to the previous afterreturning enhancements, the @Aspect is used here to decorate the front Bean, where the bold code specifies that the

"Before and After (Around)" Weaving processtx (Proceedingjoinpoint jp) method for all methods of all classes under the Org.crazyit.app.service.impl package


It should be noted that although the afterreturning, Around two enhancements to spring AOP are described here, in fact Spring also supports before, after,

Afterthrowing, such as enhanced processing, about Spring AOP programming more and more detailed programming details, you can refer to the "Lightweight Java EE Enterprise Application Combat" book.


This example uses spring's 0 configuration to turn on spring AOP, so the above Chinese class uses @Component adornments, while the aspect Bean uses @Aspect adornments,

The Advice in the Bean are @AfterReturning, @Around decorated respectively. Next, just provide the following configuration file for Spring :

 <?xml version= "1.0" encoding= "GBK"?> <beans xmlns= "Http://www.springframework.org/schema/beans" xmln             S:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "Http://www.springframework.org/schema/context" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "Http://www.springframewor K.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.spring Framework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd htt P://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- Specify Auto Search Bean component, auto Search Facet class--<context:component-scan base-package= "Org.crazyit.app.service, Org.crazyit.app.advi Ce "> <context:include-filter type=" annotation "expression=" Org.aspectj.lang.annotation.Aspect "/> & Lt;/context:component-scan&gT <!--start-up @AspectJ support-<aop:aspectj-autoproxy/> </beans>


Next, the traditional way to get the Chinese bean in the Spring container and call the Bean's two methods, the program code is as follows:

public class Beantest {public     static void Main (string[] args) {         //Create Spring container        applicationcontext ctx = new Classpathxmlapplicationcontext ("Bean.xml");         Chinese p = ctx.getbean ("Chinese", chinese.class);         System.out.println (P.sayhello ("Zhang San"));         P.eat ("watermelon");     }  }


As you can see from the development process above, there is no special place for the developer to provide business components and aspect beans for Spring AOP. Just the aspect Bean needs to be used @Aspect

Decoration can be. The program does not need to be processed using a special compiler or loom.


Running the above program, you will see the following execution results:

Simulate starting a transaction before executing the target method ...-Executing the SayHello method-after executing the target method, the simulation ends the transaction ... Get the target method return value: The changed parameter Hello, Spring AOP new content simulation logging function ... Changed parameters Hello, Spring AOP new content to execute the target method before the simulation begins the transaction ... I'm eating: After the changed parameter executes the target method, the simulation ends the transaction ... Get Target method return value: null new content simulation logging feature ...

Although the program is calling the Chinese object's SayHello, eat two methods, but the results from the above is not difficult to see: the actual execution is not the Chinese object of the square method, but the method of the AOP agent. Also

said that Spring AOP also generated an AOP proxy class for the Chinese class. This can be seen by adding the following code to the program :

System.out.println (P.getclass ());


The above code can output the implementation class of the object referenced by the P variable, and executing the program again will see that the code above produces class

org.crazyit.app.service.impl.chinese$ $EnhancerByCGLIB The output of the $$290441D2, which is the implementation class of the object referenced by the P variable, and this class is the Spring AOP dynamic

The AOP proxy class generated by the state. As can be seen from the class name of the AOP proxy class, the AOP proxy class is generated by CGLIB.


If you modify the above program slightly: just let the above business logic class Chinese class implement an arbitrary interface-this approach is more in line with Spring's advocated "interface-oriented programming" principle. Fake

The Setup program provides the following person interface for the Chinese class and enables the Chinese class to implement the interface:

Public interface Person {     string SayHello (string name);     void Eat (String food);  }

Next, let the Beantest class be programmed for the person interface instead of the Chinese class. The Beantest class will be changed to the following form:

public class Beantest {public     static void Main (string[] args) {         //Create Spring container        applicationcontext ctx = new Classpathxmlapplicationcontext ("Bean.xml");         Person p = Ctx.getbean ("Chinese", person.class);       System.out.println (P.sayhello ("Zhang San"));        P.eat ("watermelon");        System.out.println (P.getclass ());     } }

the original program is to be oriented to the Chinese class programming, now the program to the person interface programming, run the program again, the program run results have not changed. is only

System.out.println (P.getclass ()), the class $Proxy 7 is output, which means that the AOP agent is not generated by CGLIB, but the JDK dynamically generated by the manager.


The Spring AOP framework deals with the AOP proxy class by using the JDK dynamic proxy to generate an AOP proxy class if the implementation class of the target object implements the interface .

The implementation class for the target object does not implement an interface, and Spring AOP will use CGLIB to generate an AOP proxy class--but this selection process The sender is completely transparent and the developer does not need to care.


Spring AOP dynamically chooses to use the JDK dynamic agent, CGLIB to generate an AOP proxy, and if the target class implements an interface, spring AOP does not need to CGLIB the support , directly using the JDK

Proxy and Invocationhandler are provided to generate an AOP proxy.


Analysis of Spring AOP principle


as you can tell by the previous introduction, an AOP proxy is actually an object that is dynamically generated by the AOP framework, which can be used as a target object. The AOP agent contains all the methods of the target's image, but

methods in an AOP proxy differ from the methods of the target object: The AOP method adds enhanced processing to a particular pointcut and recalls the target object's method.


The AOP proxy contains methods that are shown in method 3 of the target object.


Figure 3.AOP Methods of proxy and target object



Spring's AOP agents are generated and managed by spring's IOC container, and their dependencies are managed by the IOC container. As a result, the AOP agent can directly use other beans in the container to actually

As a target, this relationship can be provided by dependency injection of the IoC container.


Throughout AOP programming, there are only 3 parts that require programmer involvement:

    • Define common business components.
    • Define Pointcuts, where a pointcut can cross-cut multiple business components.
    • Define enhanced processing, which is the processing action that the AOP framework weaves into ordinary business components.

The first part of the above 3 sections is the most common thing, without additional explanation. The key to AOP programming is defining pointcuts and defining enhanced processing. Once a suitable cut-in is defined

Point and enhanced processing, the AOP framework will automatically generate an AOP proxy, and the AOP proxy approach has the following formula:


Method of proxy object = Enhanced processing + method of proxied Object


In the business definition above, it is easy to see that the implementation of Spring AOP is simple: The AOP framework is responsible for dynamically generating the AOP proxy class, which is represented by Advice and back

The method of adjusting the target object.


For the previously mentioned software call structure shown in Figure 2: When Method 1, Method 2, Method 3 ... Need to invoke a method with a "crosscutting" nature, the traditional practice is to manually fix the

Method 1, Method 2, Method 3 ..., call this "crosscutting" method by code, but the extensibility of this practice is not good, because change the code every time.


So the AOP framework emerges, and the AOP framework can generate a new proxy class "dynamically", and the proxy class contains methods 1, 2, Method 3 ... Also added to call this with "horizontal

-but this invocation is responsible for the proxy classes generated automatically by the AOP framework, and therefore has excellent extensibility. The programmer does not need to move the manual modification Method 1, Method 2, Method 3 of the generation

code, the programmer simply defines the pointcut to--AOP the AOP proxy class generated by the framework contains a new method 1, the method of 2, Method 3, and the AOP framework depends on the pointcut to decide whether to

In Method 1, Method 2, Method 3, the callback has a "crosscutting" nature of the method.


In short: The Secret of the AOP principle is the dynamic generation of proxy classes.


Spring AOP Implementation principle (ii) using spring AOP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.