I. The concept of 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.
two. Main uses
the code for logging, performance statistics, security control, transaction processing, exception handling, and other code is separated from the business logic code, and by separating these behaviors, we want to be able to separate them into non-instructional methods of business logic, and then change these behaviors without impacting the business logic.
three. Agent
the key to AOP implementation is the AOP proxy, which is automatically created by the AOP framework. AOP proxies are divided into two main categories:
1. Static proxies: Compile using the commands provided by the AOP framework to generate an AOP proxy class at compile-time, and therefore also known as a compiler-only enhancement; a static proxy is represented by a aspectj.
2. Dynamic agent: With the help of JDK dynamic agent at run time, Cglib and so on temporarily generate AOP dynamic proxy class in memory, so it is also called run-time enhancement, and Spring AOP uses dynamic proxy.
in fact, the use of the spring framework is the JDK dynamic agent or the Cglib agent.
four. JDK Dynamic agent
JDK Dynamic Agent used a class proxy, as an example to illustrate, the proxy class is how to implement the JDK dynamic proxy.
One requirement is that when the user name is empty, the business method cannot be called, and the business method can be called when the user name is not empty.
1. Create a new business interface and write the business method.
Package Cn.service; Public Interface Doservice { // add public voidadd (); // Enquiry Public void selectinfo (); // Update Public void update ();}
2. Create a new business interface implementation class
PackageCn.service.impl;ImportCn.service.DoService; Public classDoserviceimplImplementsdoservice{//User name PrivateString UserName; @Override Public voidAdd () {System.out.println ("Added Method"); } @Override Public voidSelectinfo () {System.out.println ("Method of Query"); } @Override Public voidUpdate () {SYSTEM.OUT.PRINTLN ("Updated Method"); } PublicString GetUserName () {returnUserName; } Public voidsetusername (String userName) { This. UserName =UserName; } }
in general, if we need to make such a business demand, we will be in a way to make a judgment in all the methods is to interpret the user name is empty, obviously this is very troublesome, all we use the JDK dynamic agent, the main function---and the target object method. In this way, whether to modify the judging conditions, or search, etc., can be directly in the proxy class processing.
3. Create a proxy object factory class
PackageCN.AOP;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy;ImportCn.service.impl.DoServiceImpl;/*** Agent Factory class *@authorHyj **/ Public classJdkproxyfactoryImplementsinvocationhandler{//the proxy object to return PrivateObject obj; /*** Create proxy classes by proxy factory *@paramobj object of the class to be proxied *@return */ Publicobject Createproxyintance (Object obj) { This. obj=obj; //The first parameter is the class loader of the target object//The second parameter is the interface implemented by the target object//The third parameter passes in a Invocationhandler instance, which has a relationship to the callback. returnProxy.newproxyinstance (Obj.getclass (). getClassLoader (), Obj.getclass (). Getinterfaces (), This); } @Override Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {Object proxyobject=NULL; Doserviceimpl DS=(Doserviceimpl) obj; if(Ds.getusername ()! =NULL) {Proxyobject=Method.invoke (ds, args); }Else{System.out.println ("User name is empty, blocked"); } returnProxyobject; } PublicObject getobj () {returnobj; } Public voidsetobj (Object obj) { This. obj =obj; } }
4. Test class
Packagecn.test;Importcn.aop.JDKProxyFactory;ImportCn.service.DoService;ImportCn.service.impl.DoServiceImpl; Public classTesthappy { Public Static voidMain (string[] args) {jdkproxyfactory JPF=Newjdkproxyfactory (); Doservice DS= (Doservice) jpf.createproxyintance (NewDoserviceimpl ("FSF")); Ds.selectinfo (); }}
Steps:
- First call the Agent factory's createproxyintance (Object obj) to create the proxy class for the Doserviceimpl class.
- Within the method, call the Proxy.newproxyinstance () method to create the proxy object. The first parameter is the class loader for the target object, the second parameter is the interface implemented by the target object, and the third parameter passes to a Invocationhandler instance, which has a relationship to the callback.
- Whenever the method of the target object is invoked, the method of the Invocationhandler instance is called back, that is, the public object Invoke () method, and we can put the conditions of the restriction here, when the conditions are met, You can call the Method.invoke () method to actually invoke the target object's method, otherwise you can filter out the non-conforming call here.
five. Cglib Agent
In this step, we use a enhancer class to create proxy objects and no longer use proxies. Using the Enhancer class, you need to specify a parent class for its instance, which is our target object. In this way, our newly created object is the subclass of the target object, which is the same as the target object. In addition to this, specify a callback function that is similar to the proxy invoke ().
Generally speaking, the method of using Cglib is similar to the method of using proxy, but the proxy object and target object created by proxy all implement the same interface. The Cglib method is to inherit the target object directly.
1. Introduction of the JAR package
2. Create a class that Cglib implements the proxy
PackageCN.AOP;ImportJava.lang.reflect.Method;ImportCn.service.impl.DoServiceImpl;ImportNet.sf.cglib.proxy.Enhancer;ImportNet.sf.cglib.proxy.MethodInterceptor;ImportNet.sf.cglib.proxy.MethodProxy;/*** CGLIB Implementation Agent *@authorHyj **/ Public classCglibproxyfactoryImplementsMethodinterceptor {//the proxy object to put back PrivateObject obj; Publicobject Createproxy (Object obj) {//Assign the proxy object passed in to obj This. obj=obj; Enhancer Enhancer=Newenhancer (); //We need to specify a parent class for its instance, our target object, and the newly created object is the subclass of the target object, which is the same as the target object.Enhancer.setsuperclass ( This. Obj.getclass ()); //In addition, you specify a callback function that is similar to the Invoke () of the proxy.Enhancer.setcallback ( This); returnenhancer.create (); } @Override PublicObject Intercept (Object object, method, object[] args, methodproxy methodproxy)throwsthrowable {Object proxyobject=NULL; Doserviceimpl DS=(Doserviceimpl) obj; if(Ds.getusername ()! =NULL) {Proxyobject=Methodproxy.invoke (ds, args); }Else{System.out.println ("User name is empty, blocked"); } returnProxyobject; } }
Test Class
@Test Public void cglibproxytest () { cglibproxyfactory GB=new cglibproxyfactory (); Doserviceimpl ds= (Doserviceimpl) gb.createproxy (new Doserviceimpl ("SF")); Ds.add (); }
The JDK dynamic agent and Cglib agent based on spring AOP