公司組織的內部培訓,裏面留了一個思考作業:基於AOP的統一日誌處理
要求實現一個AOP的技術雛形,能夠實現方法的調用前、正常執行後、異常執行後以及執行後的日誌輸出;同時要求,對於Java API對象和Object的方法做攔截。
我使用了兩種方法來實現
1、利用JDK自帶的reflect包。
2、利用cglib包實現。
工程目錄:
Dao接口定義:
public interface DAO {
public void create();
public void query();
public void update();
public void delete();
}
DAOImp實現
public class DAOImp implements DAO {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("create is called!");
}
@Override
public void query() {
// TODO Auto-generated method stub
System.out.println("query is called!");
}
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("update is called!");
}
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("delete is called!");
}
}
使用JDK產生動態代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DAOProxyUsingJDK implements InvocationHandler {
private Object proxy;
public Object bind(Object proxy){
this.proxy = proxy;
return Proxy.newProxyInstance(this.proxy.getClass().getClassLoader(),
this.proxy.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
// TODO Auto-generated method stub
Object result = null;
System.out.println("事務開始");
//執行方法
result=arg1.invoke(proxy, arg2);
System.out.println("事務結束");
return null;
}
}
使用cglib來實現
import java.lang.reflect.Method;
import org.logicalcobwebs.cglib.proxy.Enhancer;
import org.logicalcobwebs.cglib.proxy.MethodInterceptor;
import org.logicalcobwebs.cglib.proxy.MethodProxy;
public class DAOProxyUsingCglib implements MethodInterceptor{
private Object target;
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回調方法
enhancer.setCallback(this);
// 創建代理對象
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
String method = arg1.getName();
if ("create".equals(method)){
System.out.println("create事務開始");
arg3.invokeSuper(arg0, arg2);
System.out.println("create事務結束");
}else
if("query".equals(method)){
System.out.println("query事務開始");
arg3.invokeSuper(arg0, arg2);
System.out.println("query事務結束");
}
else
if ("update".equals(method)){
System.out.println("update事務開始");
arg3.invokeSuper(arg0, arg2);
System.out.println("update事務結束");
}
else
if ("delete".equals(method)){
System.out.println("delete事務開始");
arg3.invokeSuper(arg0, arg2);
System.out.println("delete事務結束");
}
return null;
}
}
測試類
import DAO.DAO;
import DAOImpl.DAOImp;
import DynamicProxy.DAOProxyUsingCglib;
import DynamicProxy.DAOProxyUsingJDK;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// DAOProxyUsingJDK proxy = new DAOProxyUsingJDK();
// DAO dao = (DAO)proxy.bind(new DAOImp());
// dao.create();
DAOProxyUsingCglib proxy = new DAOProxyUsingCglib();
DAO dao = (DAO) proxy.getInstance(new DAOImp());
dao.create();
dao.query();
dao.update();
dao.delete();
}
}
運行結果:
改進的地方:
需要增加對與異常的處理
類似於Cglib簡單學習(1)
例子實現權限控制