代理模式可谓是Spring框架AOP实现的基础,无意发现当service层使用事务时,注册到spring容器的是一个proxy对象,而无事务的service注册到容器就是非proxy对象。猜想如果某一个类是aop切入点时就使用代理对象。 以下是jdk动态代理的实现
/**
*
*@Description:切面处理类
*@Author:mf
*@Since:2017年11月14日
*@Version:1.1.0
*/
public class AopInvocationHandler implements InvocationHandler {
/**
* 目标对象
*/
private Object target;
/**
* 拦截器
*/
private List<AopIntercept> chains;
public AopInvocationHandler(Object target, AopIntercept... handlers) {
chains = Arrays.asList(handlers);
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = new AopProxy(proxy, target, method, args, chains).process();
return result;
}
}
/**
*
*@Description:AOP静态代理类
*@Author:mf
*@Since:2017年11月14日
*@Version:1.1.0
*/
public class AopProxy {
private Object proxy;
private Object target;
private Method method;
private Object[] args;
private List<AopIntercept> chains;
private int index = -1;
public AopProxy(Object proxy, Object target, Method method, Object[] args, List<AopIntercept> chains) {
this.proxy = proxy;
this.target = target;
this.method = method;
this.args = args;
this.chains = chains;
}
/**
*
* @return
* @throws Throwable
* @author:mf
* @Description:如果有拦截器则先执行拦截器,若无则执行方法
*/
public Object process() throws Throwable {
if (index == chains.size() - 1) {
try {
return method.invoke(target, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
AopIntercept hander = chains.get(++index);
return hander.intercept(proxy, method, args, this);
}
/**
*
*@Description:拦截器接口
*@Author:mf
*@Since:2017年11月14日
*@Version:1.1.0
*/
public interface AopIntercept {
/**
*
* @param proxy
* @param method
* @param args
* @param aop
* @return
* @throws Throwable
* @author:mf
* @Description:
*/
public Object intercept(Object proxy, Method method, Object[] args, AopProxy aop) throws Throwable;
}
/**
*
* @Description:日志拦截器
* @Author:mf
* @Since:2017年11月14日
* @Version:1.1.0
*/
public class LoggerIntercept implements AopIntercept {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public Object intercept(Object proxy, Method method, Object[] args, AopProxy aop) throws Throwable {
String params = doBefore(method, args);// 之前记录日志
// 开始时间
long start = System.currentTimeMillis();
Object result = aop.process();// 继续执行
// 结束时间
long end = System.currentTimeMillis();
log.info("-OUT \"{}\",COST:{}", params, (end - start) + "ms");
return result;
}
private String doBefore(Method method, Object[] args) {
StringBuilder params = new StringBuilder("");
try {
params.append(method.getDeclaringClass().getName()).append(".");
params.append(method.getName());
log.info("-IN \"{}\",PARAMS:{}", params, JSON.toJSONString(args,SerializerFeature.WriteMapNullValue));
} catch (Exception e) {
log.error("LoggerIntercept", e);
}
return params.toString();
}
}
public class Test {
public static void main(String[] args) {
try {
UserService service = Class.forName("package").newInstance();
UserService serviceProx = getProxObj(UserService.class,service);
System.out.println(service);
service.save("1", "小毛");
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
*
* @param inter
* @param target
* @return
* @author:mf
* @Description:获取动态代理对象
*/
@SuppressWarnings("unchecked")
private static <T> T getProxObj(Class<T> inter, T target) {
//创建代理处理类,并添加切面处理类
AopInvocationHandler h = new AopInvocationHandler(target, new LoggerIntercept());
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), new Class[] { inter }, h);
}
}
这是一个简单的动态代理实现AOP的功能。