Spring-oriented AOP interceptor for Facets

Source: Internet
Author: User

There are many concepts and nouns in spring, some of which are different, but functionally, the total feel is similar, such as filters, interceptors, AOP, and so on.
Filters filter, Spring MVC Interceptor Interceptor, aspect-oriented programming AOP, in fact, have a certain interception function, is to intercept a certain surface, and then do some processing.
Here is the main thing to do is AOP, as for their comparison, I would like to wait for three of them all to know, so there is no excessive comparison.
In my current project practice, the use of AOP, which is shown manually in only one place, is a record of some important operations in log management.
As far as I know, AOP interception is generally used in specific ways, or a specific kind of method, I have used the implementation of two kinds, one is the direct code declaration, one is configured in the XML file.

Because I am currently developing projects that use the spring+spring MVC architecture, then use MAVEN to manage and then junit to test. So my own almost all of my personal projects are also using these architecture and project management tools, and in this small project of understanding AOP, naturally, the dependencies are as follows:

<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xsi: schemalocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > < Modelversion>4.0.0</modelversion> <groupId>springTest</groupId> <artifactid>aoptest
        </artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</ve
        rsion> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.3.RELEASE</version> </depend ency> <dependency> <groupId>org.springframework</groupId> <artifactid>sprin G-aop</artifactid> <version>4.0.3.release</version> </dependency> <dependency> &LT;GROUPID&GT;ORG.SPRINGFRAMEWORK&LT;/GROUPID&G
        T <artifactId>spring-test</artifactId> <version>4.0.3.RELEASE</version> </dependency&
    Gt <dependency> <groupId>org.aspectj</groupId> <artifactid>aspectjweaver</artifact id> <version>1.8.4</version> </dependency> </dependencies> </project>

the first way, the Java code declares:
In this example, I'm going to declare an AOP to intercept all the methods in the DAO layer for Get start, first to build a DAO and a simple amount imp to implement:
The DAO interface is as follows:

Package Com.ck.aopTest.dao;
Import Com.ck.aopTest.model.UserModel;

Public interface Myaopdao {public
    void GetUser ();
    public void GetName (Usermodel user);
    public void AddUser ();
}

A simple implementation:

Package Com.ck.aopTest.dao.impl;
Import org.springframework.stereotype.Repository;
Import Com.ck.aopTest.dao.MyAopDao;
Import Com.ck.aopTest.model.UserModel;

@Repository public
class Myaopdaoimpl implements Myaopdao {

    @Override public
    void GetUser () {
        System.out.println ("This is my AOP test dao Method One");
    }
    @Override public
    void GetName (Usermodel usermodel) {
        System.out.println ("This is my AOP test DAO Method II");
    }
    @Override public
    void AddUser () {
        System.out.println ("This is my AOP test Dao Method Three");}
}

Then declare an AOP:

Package COM.CK.AOPTEST.AOP;
Import Java.util.Date;
Import Org.aspectj.lang.ProceedingJoinPoint;
Import Org.aspectj.lang.annotation.After;
Import Org.aspectj.lang.annotation.Around;
Import Org.aspectj.lang.annotation.Aspect;
Import Org.aspectj.lang.annotation.Before;
Import Org.aspectj.lang.annotation.Pointcut;
Import org.springframework.stereotype.Component;

Import Com.ck.aopTest.model.UserModel;
    @Aspect @Component public class Myaop {@Pointcut ("Execution (public * com.ck.aoptest.dao.impl.*.get* (..))") private void Aoptest () {} @Before ("Aoptest ()") public void before () {System.out.println ("intercept before the DAO method is called")
    "+ New Date (). GetTime ()); } @After ("Aoptest ()" + "&&args (user)") public void after (Usermodel user) {System.out.println (user
        . GetName ());
    System.out.println ("Block after calling DAO method" + New Date (). GetTime ()); } @Around ("Aoptest ()") public void Around (Proceedingjoinpoint pdj) {System.out.println ("Surround Intercept before calling DAO" + N ew Date (). GetTime ());
        try {pdj.proceed ();
        } catch (Throwable e) {e.printstacktrace ();
    } System.out.println ("Surround Intercept after calling DAO" + New Date (). GetTime ()); }
}

The code above is the core code for using Java to declare AOP, where annotations @aspect the role of telling Spring that this is an AOP class, and then @component don't have to say it, tell Spring that this is a class that needs to be scanned.
Further down, @Pointcut (Execution (public * com.ck.aopTest.dao.impl). Get (..)) ") Formally declare the section to be intercepted, @Pointcut and the execution in the back is a fixed notation, and the contents of the execution brackets are specific facets, meaning to intercept any return value of all public or void, A namespace is a method that has any number of arguments at the beginning of all get in all the classes below Com.ck.aopTest.dao.impl. The
simple point is that the AOP is activated when any method that invokes the get start of a Com.ck.aopTest.dao.impl in any class in the package is invoked.
and immediately above this paragraph, we see a private void Aoptest () null method, in fact, the function of this method is to declare a name for this AOP slice, easy to use, but also easy to distinguish between multiple AOP facets. The
@before, @After, @Around is the three selectable interception methods, see the meaning of the name, respectively, in the above-declared aspect of the method call before execution, after the call execution, and wrapping execution, call before and after the call better understanding, Wrapping means executing certain logic before and after the call. The
can be seen from the Code, Pdj.proceed (); Two lines of data were printed before and after, Pdj.proceed (); It represents the continuation of the execution, If it is understood that the filter should be very easy to think of this method is actually similar to Chain.dofilter, can be understood as release.
After these three annotations you need to specify the slice you want to use, that is, the tangent of the @pointcut declaration, specifying the name.
You can see from the code that there is a place behind "&&args (Usermodel user)", which means specifying a parameter, that is, the parameters of a valid method in the specified slice, For example, the GetName method in DAO above has a parameter of type Usermodel, which can be used here.
The main code is written, and then there is an essential step, since the spring project, which is spring AOP, then naturally needs to configure the spring file to indicate the packages that need spring management:

<?xml version= "1.0" encoding= "UTF-8"?> <beans  
xmlns= "Http://www.springframework.org/schema/beans" 
    xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context= "http://www.springframework.org/ Schema/context ""  
    xsi:schemalocation= "Http://www.springframework.org/schema/beans/  
    http Www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    Http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd "> 
    <context:component-scan Base-package= "com.ck.aoptest.*"/>
</beans>

To verify that AOP is really working here, I wrote a junit test:

Package com.ck.aopTest.test;
Import Org.junit.Test;
Import Org.junit.runner.RunWith;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.test.context.ContextConfiguration;
Import Org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
Import Com.ck.aopTest.dao.MyAopDao;
Import Com.ck.aopTest.model.UserModel;

@RunWith (Springjunit4classrunner.class)
@ContextConfiguration (locations = "Classpath:spring.xml")
public Class Aoptest {
    @Autowired
    private Myaopdao Myaopdao;

    @Test public
    void AopTest2 () {
        Usermodel user = new Usermodel ();
        Myaopdao.getname (user);
    }
}

It's supposed to print a lot of output after running the test method, but unfortunately the result just prints out a single output in DAO, because AOP is not enabled in the spring configuration, and the correct configuration should be the following:

<?xml version= "1.0" encoding= "UTF-8"?> <beans  
xmlns= "Http://www.springframework.org/schema/beans" 
    xmlns: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.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    Http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/ Spring-context-3.0.xsd
    HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP
    Http://www.springframework.org/schema /aop/spring-aop-4.0.xsd "> 

    <aop:aspectj-autoproxy/>
    <context:component-scan base-package=" com.ck.aoptest.* "/>   

</beans>

We need to add the file header.

xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"

And

Http://www.springframework.org/schema/aop
Http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

In addition to this, you also enable AOP:

<aop:aspectj-autoproxy/>

Running the test method again will see the console as follows:

This proves that this AOP is effective.

The second way, configuration file configuration:
Similarly, the previous DAO and the corresponding impl are used here, so this code is no longer duplicated, but the specific AOP classes are as follows:

Package COM.CK.AOPTEST.AOP;
public class MyAop2 {public
    void Before2 () {
        System.out.println ("This is my AOP using annotations, which is called before DAO is intercepted");}
}

Can see this class is actually extremely simple, ordinary class, ordinary method, no special, and then we have to do is to configure in spring:

<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns= "Http://www.springframework.org/schema/beans" Xmlns:xs I= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "Http://www.springframework.org/schema/context" xml ns: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/c Ontext http://www.springframework.org/schema/context/spring-context-3.0.xsd Http://www.springframework.org/schem A/AOP http://www.springframework.org/schema/aop/spring-aop-4.0.xsd "> <aop:aspectj-autoproxy/> < Bean id= "MYAOP2" class= "Com.ck.aopTest.aop.MyAop2" ></bean> <aop:config> <aop:pointcut Expressi on= "Execution (public * com.ck.aoptest.dao.impl.*.add* (..))" id= "AopTest1"/> <aop:aspect id= "MyAopTest2" ref= "M YAop2 "> <aop:befoRe method= "Before2" pointcut-ref= "AopTest1"/> </aop:aspect> </aop:config> <context:compone Nt-scan base-package= "com.ck.aoptest.*"/> </beans>

As for the specific explanation of the configuration here, I think that after my interpretation of the first way, there is not much need to say, a little contrast will be clear.
Similarly, only before is shown here, and the configuration of after and round should also be easily inferred from before.

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.