Java USES a dynamic proxy to implement AOP of logging instance code
- 2020-04-01 02:20:02
- OfStack
Here is a simple example of an AOP implementation:
< img border = 0 SRC = "/ / files.jb51.net/file_images/article/201309/2013927153107998.jpg" >
Start by defining some business methods:
public interface BussinessService {
public String login(String username, String password);
public String find();
}
public class BussinessServiceImpl implements BussinessService {
private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
@Override
public String login(String username, String password) {
return "login success";
}
@Override
public String find() {
return "find success";
}
}
public interface WorkService {
public String work();
public String sleep();
}
public class WorkServiceImpl implements WorkService{
@Override
public String work() {
return "work success";
}
@Override
public String sleep() {
return "sleep success";
}
}
Implement the InvocationHandler interface and use a map to store different InvocationHandler objects to avoid excessive generation.
package com.wangjie.aoptest2.invohandler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.logging.Logger;
public class LogInvoHandler implements InvocationHandler{
private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
private Object target; //The proxy target
private Object proxy; //Proxy objects
private static HashMap<Class<?>, LogInvoHandler> invoHandlers = new HashMap<Class<?>, LogInvoHandler>();
private LogInvoHandler() {
}
public synchronized static<T> T getProxyInstance(Class<T> clazz){
LogInvoHandler invoHandler = invoHandlers.get(clazz);
if(null == invoHandler){
invoHandler = new LogInvoHandler();
try {
T tar = clazz.newInstance();
invoHandler.setTarget(tar);
invoHandler.setProxy(Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(), invoHandler));
} catch (Exception e) {
e.printStackTrace();
}
invoHandlers.put(clazz, invoHandler);
}
return (T)invoHandler.getProxy();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target, args); //Perform business processing
//Print log
logger.info("____invoke method: " + method.getName()
+ "; args: " + (null == args ? "null" : Arrays.asList(args).toString())
+ "; return: " + result);
return result;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {
return proxy;
}
public void setProxy(Object proxy) {
this.proxy = proxy;
}
}
Then write a Test class called Test:
public class Test {
public static Logger logger = Logger.getLogger(Test.class.getSimpleName());
public static void main(String[] args) {
BussinessService bs = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
bs.login("zhangsan", "123456");
bs.find();
logger.info("--------------------------------------");
WorkService ws = LogInvoHandler.getProxyInstance(WorkServiceImpl.class);
ws.work();
ws.sleep();
logger.info("--------------------------------------");
BussinessService bss = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
bss.login("lisi", "654321");
bss.find();
}
}
The new business logic XXXService needs to be added later, just called
XXXService xs = LogInvoHandler. GetProxyInstance (XXXServiceImpl. Class);
Can.
You can also simulate the configuration of frameworks such as Spring by configuring the class name of the bean in an XML file, such as:
< BussinessService bean id = "" class =" com. Wangjie. Aoptest2. Service. Impl. BussinessServiceImpl ">
And then parse the XML in the Java code, by Class. The class.forname (" com. Wangjie. Aoptest2. Service. Impl. BussinessServiceImpl "); Get the Class object
Then through LogInvoHandler. GetProxyInstance (class.forname (" com. Wangjie. Aoptest2. Service. Impl. BussinessServiceImpl ")); Get the Proxy object Proxy
Reflection is then used to invoke the methods of the proxy object.
The operation results are as follows:
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: login; The args: [zhangsan, 123456]; Return: the login success
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: find; The args: null; Return: find success
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Test the main
INFO: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: the work; The args: null; Return: work success
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: sleep; The args: null; Return: sleep success
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Test the main
INFO: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: login; The args: [lisi, 654321]; Return: the login success
September 24, 2013 com 11:08:03 morning. Wangjie. Aoptest2. Invohandler. LogInvoHandler invoke
INFO: ____invoke method: find; The args: null; Return: find success