Aspect Oriented Programming (AOP), cutting-oriented, is a hot topic. The purpose of AOP is the purpose of extracting the sections of the business process, which faces a step or phase in the process of processing to obtain a low coupling between the portions during logic. For example, our most common is the log record, give an example, we now provide a service to query student information, but we want to record who is in this query. If we implement the traditional OOP implementation, then we implemented a service interface (StudentInfoservice) and its implementation class (StudentInfoserviceImpl.java), and at the same time we are implementing the class (StudentInfoserviceImpl.java) In order to add the process of implementing its record. In this case, if the service we want to achieve is there? Then add these recording procedures at each implementation class. If this is done, it will be a bit cumbersome, and each implementation class is tightly coupled to the behavior of the log service log, which violates the object-oriented rules. So how can I separate the behavior of the record service from the business process? It seems that it is to query the students' service yourself, but the logging behind these behaviors is recorded, but the student's service does not know that there are these records, which is what we want to discuss the purpose of AOP. AOP programming, it seems to bring us in a part of the function to isolate it, which reduces coupling between a batch of objects, which can be programmed on a function.
Let's start from the code. To implement the above goals, we can use a dynamic proxy class (Proxy), complete by intercepting an object's behavior and adds the features we need. Java.lang.Reflect.Proxy class and java.lang.reflect.invocationHandler interface provide a scheme for us to implement dynamic proxy classes, but the object is targeted to some interfaces; if the purpose is class CGLIB provides us with another implementation. The difference between the two will be explained.
First, the implementation of the interface:
1) First write our business interface (StudentInfoservice.java):
Public interface studentinfoservice {
Void FindInfo (String StudentName);
}
And its implementation class (StudentInfoserviceImpl.java):
Public Class StudentInfoserviceImpl Implements StudentInfoservice {
Public void findInfo (string name) {
System.out.println ("The name you currently entered is:" Name);
}
}
2) Now we need a log function, execute and record its behavior before the FindInfo behavior, then we must first intercept the behavior. During the actual implementation process, use a proxy class for us. Java provides us with a scheme for realizing dynamic agents:
1 'Handling interceptor (MyHandler.java) Import Org.Apache.log4j.logger; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {private Object proxyObj; private static Logger log = Logger.getLogger (MyHandler.class); public Object bind (Object obj) {this.proxyObj = obj;. return Proxy.newProxyInstance (obj.getClass () getClassLoader (), Obj.getClass (). GetInterface (), this);} public object invoke (Object Proxy, Method Method, Object [] args) throws throwable {Object Result = null; try {// Please insert code here, Call log.info before the method ("call log log method" method.getName ()); result = method.invoke (proxy = //); (EXCEPTION E) {E.PrintStackTrace ();} Return Result;}} 2 'We implement a factory, in order to facilitate us to use this interception class (AOPFactory.java): public class aopfactory {private static object getClassInstance (String clzname) { Object obj = null; try {Class cls = Class.forName (clzName); obj = (Object) cls.newInstance ();} catch (ClassNotFoundException cnfe) {System.out.println ( "ClassNotFoundException:" cnfe.getMessage ( )));} CatCH (Exception E) {E.PrintStackTrace ();} returnobj;} public static Object getAOPProxyedObject (String clzName) {Object proxy = null; MyHandler handler = new MyHandler (); Object obj = getClassInstance (clzName); if (! obj = null) {proxy = handler.bind (obj);} else {System.out .println ("can't get the proxyobj); // throw} Return Proxy;}}
3) interceptor to its basic factory we have achieved, and now test (ClientTest.java): public class ClientTest {public static void main (String [] args) {StudentInfoService studentInfo = (StudentInfoService) AOPFactory.getAOPProxyedObject ( "StudentInfoServiceImpl"); StudentInfo.findInfo ("A Fei");}} Output (see your log4j setting): [INFO] call log log method FindInfo The name you currently entered is: A Fei, we need the effect, business handles yourself Perform, but we implemented logging, while business processing (StudentInfoservice) does not know that there is this behavior. However, the implementation of the dynamic agent classes provided in Java is a class that implements certain interfaces. If the interface is not implemented, the agent class cannot be created, and the above part: Return Proxy.NewProxyInstance (Obj.getClass (). GetClassLoader (), Obj.getClass (). getInterfaces (), this); did you see it? Obj.getClass (). getInterfaces () requires some interfaces. The following provides an implementation scheme without an interface: Second, a subclass implementation scheme. First, please go to the CGLIB package, http://sourceforge.net/project/showfiles.php? Group_id = 56933. Set the ClassPath path, the implementation of the CGLIB and the Java standard library is different, CGLIB is primarily based on the implementation class (such as StudentInfoserviceImpl.java) to extend a subclass. Compared to Proxy and InvocationHandler in Dynamic Proxy, net.sf.cglib.proxy.enhancer and MethodInterceptor are responsible for completing the proxy object creation and method intercept processing in CGLIB, generating a subclass of the target class rather than through an interface Interception, enhancer is mainly used to construct dynamic agent subclasses to implement interception, MethodInterceptor (extended Callback interface) is mainly used to implement Around Advice (Concept in AOP): 1) Our business processing (studentinfoserviceImpl.java): public Class StudentInfoserviceImpl {public void FindInfo (String Name) {system.out.println ("The name you currently entered is:" name);}} 2) Implement a tool to process log function (AOPINSTRUMENTER.JAVA): import Net. Sf.cglib.proxy.methodinterceptor; import net.sf.cglib.proxy.enhance; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import org.apache.log4j.logger;
public class AOPInstrumenter implements MethodInterceptor {private Logger log = Logger.getLogger (AOPInstrumenter.class); private Enhancer enhancer = new Enhancer (); public Object getInstrumentedClass (Class clz) {enhancer.setSuperclass (clz); enhancer.setCallback (this); return enhancer.create ();} public Object intercept (Object o, method method, Object [] args, MethodProxy proxy) throws Throwable {log.info ( "call log method" method.getName ()); Object result = proxy .invokeSuper (o, args); return result;}} 3) Let's test (AOPTest.java): public class AOPTest {public static void main (String [] args) {AOPInstrumenter instrumenter = new AOPInstrumenter (); StudentInfoServiceImpl studentInfo = (StudentInfoserviceImpl) Instrumenter.getinstrumentedClass (StudentInfoserviceImpl.class); StudentInfo.findInfo ("A Fei");}} The output result is the same as above. In CGLIB, the primary, mainly provided class 1) enhancer: setCallback (Callback), setsuperclass (class), create () return Dynamic subclass Object2) MethodInterceptor must be implemented interface: Intercept (Object, Method, Object [], MethodProxy) Returns the result of the original method call. Like the proxy principle.
Third, the above two simple implementation AOP programs are ready for you, you can write tests yourself, here is briefly introduced the basic concept of AOP: 1) Aspect: Implement the cross-cutting function, it is Sliced modules. The most common is the Logging module, so that the program is divided into several layers, if the traditional inheritance, the business model inherits the log module, and the AOP can be used by creating a logging section. Function. 2) JointPoint: The connection point is where the part is inserted into the application, which can be called by the method, and it will be thrown. The connection point is where the application is provided to the cut surface, and a new method can be added. For example, our cutting point can be considered a FindInfo (String) method. 3) Advice: Advice is the implementation of our cutting function, which notifies the program new behavior. For logging, Logging Advice includes logging implementation code, such as writing logs to a file. Advice is inserted into the application at JointPoint. The above we have implemented Advice Functions in MyHandler.java. . I decided that JointPoint would get notifications. 5) Introduction: Allows the addition of new methods and properties to the class. 6) TARGET: means those classes that will use Advice generally refer to those business models. For example, STUDENTINFOSERVICEIMPL.7) Proxy: Use Proxy mode. Refers to the application of Advice, it looks like Target objects. 8) Weaving: means the process of applying aspects to a Target object to create an Proxy object: Complie Time, ClassLoad Time, Runtime