AOP in Spring

Source: Internet
Author: User
Tags aop prepare throwable

The content of this section:

    • Introduction to AOP
    • The implementation principle of Spring bottom AOP
    • Spring's AOP nouns
    • Development of AOP in spring

First, the introduction of AOP

1. What is AOP

In the software industry, AOP is the abbreviation for Aspect oriented programming, which means: face-cutting programming, through the pre-compilation method and runtime dynamic agent to implement the unified maintenance of the program functions of a technology. AOP is a continuation of OOP, a hotspot in software development, an important content in the spring framework, and a derivative model of functional programming. AOP enables the isolation of parts of the business logic, which reduces the coupling between parts of the business logic, improves the reusability of the program, and improves the efficiency of development.

Spring is a solution to some of the problems in real-world development:

    • AOP solves some of the problems that are encountered in OOP. is the continuation and extension of OOP.

"Note": Spring provides support for AOP programming of objects, not that spring itself can be AOP. Spring acts as a container for objects that can help generate dynamic proxy objects for objects that are managed in a container. The previous generation of dynamic proxy objects required the writing of their own code, and spring could help us generate proxy objects, requiring only configuration files or annotations.

AOP thought: horizontal repetition, longitudinal extraction.

AOP is a thought, in every business, in the field will be reflected, the first in the filter, servlet solution garbled. Do not learn filter before, to solve the garbage is annoying, each time to receive parameters to solve the parameter garbled, so each servlet to set the solution garbled. When we use the filter, the request arrives at the servlet before the filter, so we will solve the garbled code in the filter, so all the servlet garbled code can be discarded, see. From the system architecture diagram, the filter solves the problem of garbled, equal to the code added to all the servlet class, so that the plane formed, so-called aspect-oriented programming.

Dynamic proxies have also used this AOP idea: Using dynamic Proxy technology to add this extracted handler to all the service to form proxy objects.

There is also an example of an interceptor, which also uses the idea of AOP:

2. Why Learning AOP

Enhance the program: without modifying the source code

    • AOP can perform permissions checking, logging, performance monitoring, and transaction control.

3. The origin of Spring's AOP

AOP was first proposed by the organization of AOP alliances, and a set of specifications was developed. Spring introduces the idea of AOP into the framework and must adhere to the specifications of the AOP Alliance.

4. The underlying implementation

Proxy mechanism: The bottom of Spring's AOP uses two kinds of proxy mechanisms:

    • Dynamic agent for JDK: Generates a proxy for the class that implements the interface.
    • Dynamic agent for Cglib: Generates proxies for classes that do not implement interfaces. The underlying bytecode enhancement technique is applied to generate subclass objects for the current class.

Second, the implementation principle of Spring bottom AOP

Proxy mechanism: The bottom of Spring's AOP uses two kinds of proxy mechanisms:

    • Dynamic agent for JDK: Generates a proxy for the class that implements the interface.
    • Dynamic agent for Cglib: Generates proxies for classes that do not implement interfaces. The underlying bytecode enhancement technique is applied to generate subclass objects for the current class.

There is a limitation in the use of dynamic agents, the proxy object must implement the interface to produce proxy objects. If the proxy object does not have an interface, dynamic agent technology cannot be used. So to ensure that each object can generate proxy objects, spring incorporates a third-party agent technology: Cglib Proxy. The agent technology is the proxy for any class generation agent whose agent is the inheritance agent for the target object. If the target object is final decorated, then the class cannot be Cglib proxy.

So what proxy method does spring use to generate proxy objects?

Mixed. If the proxy object has an interface, the dynamic proxy is used preferentially. If there is no interface, use the Cglib proxy.

Example: Use dynamic agents and CGLIB agents to complete the proxy for the class, respectively. (Insert the transaction code where the transaction is needed)

Examples of dynamic proxy code:

Interface Userservice.java

Package com.wisedu.service;/** * Created by Jkzhao on 12/12/17. */public interface UserService {    void Save ();    void Delete ();    void Update ();    void find ();}

Userserviceimpl.java by proxy Object

Package com.wisedu.service;/** * Created by Jkzhao on 12/12/17. */public class Userserviceimpl implements UserService {    @Override public    Void Save () {        // SYSTEM.OUT.PRINTLN ("open transaction");        System.out.println ("Save User");        SYSTEM.OUT.PRINTLN ("Commit Transaction");    }    @Override public    Void Delete () {        System.out.println ("delete user");    }    @Override public    Void Update () {        System.out.println ("Update user");    }    @Override public    Void Find () {        System.out.println ("Find User");}    }

Proxy object class Userserviceproxyfactory.java

Package Com.wisedu.proxy;import Com.wisedu.service.userservice;import Com.wisedu.service.userserviceimpl;import Java.lang.reflect.invocationhandler;import java.lang.reflect.method;import java.lang.reflect.proxy;/** * Created by Jkzhao on 12/12/17.        */public class Userserviceproxyfactory implements invocationhandler{public userserviceproxyfactory (userservice us) {    this.us = us;    } private UserService us; Public UserService getuserservicefactory () {//Returns UserService proxy object//Generate dynamic proxy return userservice Usproxy = (Userservi CE) proxy.newproxyinstance (UserServiceProxyFactory.class.getClassLoader (), USERSERVICEIMPL.C        Lass.getinterfaces (), this);    return usproxy; } @Override public object invoke (object proxy, Method method, object[] args) throws Throwable {SYSTEM.OUT.PR        INTLN ("open transaction"); Object invoke = Method.invoke (us, args);        The invocation of the original method System.out.println ("Commit Transaction");    return invoke; }}

Test Code Demo.java

Package Com.wisedu.proxy;import Com.wisedu.service.userservice;import Com.wisedu.service.userserviceimpl;import org.junit.test;/** * Created by Jkzhao on 12/13/17. */public class Demo {    @Test public    void Fun1 () {        userservice us = new Userserviceimpl ();//Create proxied object        Userserviceproxyfactory factory = new Userserviceproxyfactory (US);        UserService usproxy = Factory.getuserservicefactory (); Proxy Object        usproxy.save ();    }}

Cglib Proxy code example: (Spring consolidates cglib and does not need to import other packages)

Userserviceproxyfactory2.java

Package Com.wisedu.proxy;import Java.lang.reflect.invocationhandler;import Java.lang.reflect.method;import Java.lang.reflect.proxy;import Org.springframework.cglib.proxy.callback;import Org.springframework.cglib.proxy.enhancer;import Org.springframework.cglib.proxy.methodinterceptor;import Org.springframework.cglib.proxy.methodproxy;import Com.wisedu.service.userservice;import com.wisedu.service.userserviceimpl;//Tourist Code =>cglib agent (Cglib is primarily an inheritance agent for classes) public class UserServiceProxyFactory2 Implements Methodinterceptor {public UserService getuserserviceproxy () {Enhancer en = new enhancer ();// Help us Generate proxy object En.setsuperclass (userserviceimpl.class);//Set the agent (Cglib mainly to the class to inherit the proxy, you have to tell it who the father is) En.setcallback (this); What the agent wants to do userservice US = (userservice) en.create ();//Create proxy object return us; @Overridepublic Object Intercept (Object Prxoyobj, method, object[] arg, Methodproxy methodproxy) throws Throwable { Open transaction System.out.println ("Open transaction!"); /Call the original method Object returnvalue = Methodproxy.invokesuper (Prxoyobj, arg);//COMMIT Transaction SySTEM.OUT.PRINTLN ("COMMIT TRANSACTION!"); return returnvalue;}}

Test method

    @Test public    void Fun2 () {        UserServiceProxyFactory2 factory = new UserServiceProxyFactory2 ();        UserService usproxy = Factory.getuserserviceproxy (); Proxy Object        usproxy.save ();        System.out.println (Usproxy instanceof Userserviceimpl);    }

The dynamic proxy is for the interface, and the Cglib proxy inherits the Proxied object.

But the code doesn't make much sense, and we'll know how to configure it in the future when we use spring, so we don't have to write it ourselves.

Three, spring's AOP nouns
    • Joinpoint (Connection point): The so-called connection point refers to the points that are intercepted. In spring, these points refer to methods because spring only supports connection points of method types.
    • Pointcut (pointcut): The so-called pointcut is the definition of which joinpoint we want to intercept.
    • Advice (Notification/enhancement): the so-called notification refers to the interception to Joinpoint after the thing to do is to notify. Notification is divided into pre-notification, post-notification, exception notification, final notification, surround notification (slice to complete the function)
    • Target object: The target object of the agent
    • Weaving (weaving): refers to the process of applying an enhancement to a target object to create a new proxy object. Spring is woven with dynamic agents, while AspectJ is woven into the stage with the compile-time and class-loaded
    • Proxy: When a class is augmented by AOP, it produces a result proxy class
    • Aspect (tangent): a combination of pointcuts and notifications (referrals)

Iv. development of AOP in spring

1. Guide Package

4+2+2+2:4 a spring core pack, 2 log packages, 2 (Spring's AOP package: Spring-aop-4.2.4.release.jar and Spring-aspects-4.2.4.release.jar), 2 (spring requires third-party AOP packages: Com.springsource.org.aopa Lliance-1.0.0.jar and Com.springsource.org.aspectj.weaver-1.6.8.release.jar)

2. Prepare the target object

Use the Userserviceimpl in the example above as the target object.

Package com.wisedu.service;/** * Created by Jkzhao on 12/12/17. */public class Userserviceimpl implements UserService {    @Override public    Void Save () {        // SYSTEM.OUT.PRINTLN ("open transaction");        System.out.println ("Save User");        SYSTEM.OUT.PRINTLN ("Commit Transaction");    }    @Override public    Void Delete () {        System.out.println ("delete user");    }    @Override public    Void Update () {        System.out.println ("Update user");    }    @Override public    Void Find () {        System.out.println ("Find User");}    }

3. Define notifications (Enhanced)

How do you define notifications in spring? Use the method to define the notification. Build a package, COM.WISEDU.SPRINGAOP, and then create a new class in the package, placing the notification in the class. As follows:

Myadvice.java

Package Com.wisedu.springaop;import org.aspectj.lang.proceedingjoinpoint;//notification class (Notification: Enhanced code) public class Myadvice {// Pre-notification//|-call//post notification before the target method runs (if an exception is not called)//|-call/surround notification after the target method is run//|-call//exception intercept notification before and after the target method//|-If an exception occurs, the//post notification is called ( Called whenever an exception occurs)//|-call//----------------------------------------------------------------//Pre-notification public void after the target method has run Before () {System.out.println ("This is the pre-notification!!");} Post-notification public void afterreturning () {System.out.println ("This is a post-notification (if an exception is not called)!");} Surround notification (the most special notification to control the invocation of the target method, which is the need to manually call the target method, add enhanced code before and after the target method), public Object around (Proceedingjoinpoint PJP) throws Throwable {System.out.println ("This is the part before wrapping the notice!"); O Bject proceed = Pjp.proceed ();//Call the target method System.out.println ("This is part of the surround notification!"); return proceed;} Exception notification public void Afterexception () {System.out.println ("Something's wrong!!!!!");} Post-notification public void after () {System.out.println ("This is a post-notification (an exception will also be called)!");}}

4. Configure to weave notifications into target objects

Applicationcontext.xml

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns= "Http://www.springframework.org/schema/beans" xmlns:context= "Http://www.springframework.org/schema/context" XM lns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "http://www.springframework.org/schema/ Beans Http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/c Ontext http://www.springframework.org/schema/context/spring-context-4.2.xsd Http://www.springframework.org/sch  EMA/AOP http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "><!--Preparation: Importing an AOP (constrained) namespace--><!-- 1. Configure the target object--><bean name= "UserService" class= "Com.wisedu.service.UserServiceImpl" ></bean><!--2. Configuring the Notification Object--><bean name= "Myadvice" class= "Com.wisedu.springaop.MyAdvice" ></bean><!--3. Configuration to weave notifications into target objects- -><aop:config><!--Configure pointcuts (target object which methods are to be increasedStrong), Expressions: public void Com.wisedu.service.UserServiceImpl.save () void Com.wisedu.service.UserServiceImpl.save () The default value is for the public method, and public can omit * com.wisedu.service.UserServiceImpl.save () from the Save method that does not require the return value under the class, and change the void to * * Com.wisedu.service.userserviceimpl.* () does not require the method, but requires the method null parameter * com.wisedu.service.userserviceimpl.* (..) to the parameters do not require, there is no line, there is also line   * Com.wisedu.service.*serviceimpl.* (..) Do not ask for classes, look for all the methods in the class that end with Serviceimpl under the service package. Expressions close to the real project * Com.wisedu.service.  *serviceimpl.* (..) Service sub-package will also go to find--><aop:pointcut expression= "Execution (* com.wisedu.service.*serviceimpl.* (..))" id= "PC"/ > <!--ID random, is to start a name, expression is the focus--><aop:aspect ref= "Myadvice" > <!--the description of the notification--><!-- Refer to the Before method as a pre-notification--><aop:before method= "before" pointcut-ref= "PC"/><!--post--&GT;&LT;AOP: After-returning method= "afterreturning" pointcut-ref= "PC"/><!--surround notification--><aop:around method= "around" pointcut-ref= "PC"/><!--exception intercept notification--><aop:after-throwing method= "afterexception" pointcut-ref= "PC"/><!--rear--><aop:after method= "after" pointcut-ref= "PC"/></aop:aspect></aop:config ></beans>

Test class Demo.java

Package Com.wisedu.springaop;import Javax.annotation.resource;import Org.junit.test;import Org.junit.runner.runwith;import Org.springframework.context.applicationcontext;import Org.springframework.context.support.classpathxmlapplicationcontext;import Org.springframework.test.context.contextconfiguration;import Org.springframework.test.context.junit4.springjunit4classrunner;import Com.wisedu.service.UserService; @RunWith ( Springjunit4classrunner.class) @ContextConfiguration ("Classpath:com/wisedu/springaop/applicationcontext.xml") public class Demo {@Resource (name= "UserService") private userservice us;//obtained here is already userservice proxy object @testpublic void Fun1 () {us.save ();//If you want to make the exception notification effective, you need an exception in the Save () method, such as int i=0/1;}}

5. Spring's AOP annotation configuration (Learn)

(1) Guide Package

Same as above, 4+2+2+2

(2) Prepare target object

Just like the top.

(3) Preparation notice

Just like the top.

(4) Configure the Weave in

Applicationcontext.xml

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns=       "Http://www.springframework.org/schema/beans" 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-4.2.xsd http://www.springframework.org/schema/ Context Http://www.springframework.org/schema/context/spring-context-4.2.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SC HEMA/AOP http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "><!--Preparation: Importing an AOP (constrained) namespace--><!- -1. Configure the target object--><bean name= "UserService" class= "Com.wisedu.service.UserServiceImpl" ></bean><!--2. Configure the Notification object--><bean name= "Myadvice" class= "Com.wisedu.annotationaop.MyAdvice" ></bean><!--3. Turn on using annotations to finish weaving--><aop:aspectj-autoproxy></aop:aspectj-aUtoproxy></beans> 

Myadvice.java

Package Com.wisedu.annotationaop;import Org.aspectj.lang.proceedingjoinpoint;import Org.aspectj.lang.annotation.after;import Org.aspectj.lang.annotation.afterreturning;import Org.aspectj.lang.annotation.afterthrowing;import Org.aspectj.lang.annotation.around;import Org.aspectj.lang.annotation.aspect;import Org.aspectj.lang.annotation.before;import The ORG.ASPECTJ.LANG.ANNOTATION.POINTCUT;//notification class @aspect//indicates that the class is a notification class public class Myadvice {@Pointcut ("Execution (* com.wisedu.service.*serviceimpl.* (..)) ") public void pc () {}//pre-notification//Specifies that the method is a pre-notification and formulates pointcut @before ("myadvice.pc ()") public void before () {System.out.println ("This is the predecessor notification !!");} Post notification @afterreturning ("execution (* com.wisedu.service.*serviceimpl.* (..))") public void afterreturning () {System.out.println ("This is a post-notification (if an exception is not called)!"); Surround notification @around ("execution (* com.wisedu.service.*serviceimpl.* (..))") Public Object Around (Proceedingjoinpoint pjp) throws Throwable {System.out.println ("This is the part before wrapping the notification!"); O Bject proceed = Pjp.proceed ()//Call the target method System.out.println ("This is after the surround notificationSection! "); return proceed;} Exception notification @afterthrowing ("execution (* com.wisedu.service.*serviceimpl.* (..))") public void Afterexception () {System.out.println ("Something's wrong!!!!!");} Post notification @after ("execution (* com.wisedu.service.*serviceimpl.* (..))") public void After () {System.out.println ("This is a post-notification (an exception is also called)!");}}

Test class Demo.java

Package Com.wisedu.annotationaop;import Javax.annotation.resource;import Org.apache.commons.logging.log;import Org.apache.commons.logging.logfactory;import Org.junit.test;import Org.junit.runner.runwith;import Org.springframework.test.context.contextconfiguration;import Org.springframework.test.context.junit4.springjunit4classrunner;import Com.wisedu.service.UserService; @RunWith ( Springjunit4classrunner.class) @ContextConfiguration ("Classpath:com/wisedu/annotationaop/applicationcontext.xml public class Demo {private static final Log logger = Logfactory.getlog (Demo.class); @Resource (name= "UserService") Private userservice us; @Testpublic void Fun1 () {Us.save ();}}

  

AOP in Spring

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.