JDK动态代理在添加前、后置处理时存在的缺陷?
1 接口:
public interface IUser {
void say();
}
2 目标类:
public class UserImpl implements IUser {
@Override
public void say() {
System.out.println("hello world");
}
}
3 代理类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestProxy implements InvocationHandler {
private Object target;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置通知");
Object obj = method.invoke(target, args);
System.out.println("后置通知");
return obj;
}
public Object createProxy(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
public static void main(String[] args){
TestProxy testPro = new TestProxy();
IUser userImpl = (IUser) testPro.createProxy(new UserImpl());
userImpl.say();
}
}
4 运行结果:
前置通知
hello world
后置通知
1 拦截的目标方法封装的实体类
import lombok.Data;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Data
public class Invocation {
public Method method;
public Object target;
public Object[] args;
public Invocation(Object proxy, Method method, Object[] args) {
this.target = proxy;
this.method = method;
this.args = args;
}
//执行目标方法
public Object process(){
Object obj=null;
try {
obj = method.invoke(target, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return obj;
}
}
2 代理类实现:
import lombok.Data;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@Data
public class MyProxy implements InvocationHandler {
private Interceptor interceptor;
private Object target;
public MyProxy(Interceptor interceptor, Object target) {
this.interceptor = interceptor;
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Invocation invocation = new Invocation(target, method, args);
return interceptor.interceptor(invocation);
}
}
3 拦截接口Interceptor
public interface Interceptor {
//拦截方法
Object interceptor(Invocation invocation);
//创建代理对象
Object plugin(Object obj);
}
4拦截接口实现:
mport java.lang.reflect.Proxy;
public class ServiceInterceptor implements Interceptor{
@Override
public Object interceptor(Invocation invocation) {
System.out.println("业务处理前置通知");
Object obj = invocation.process();
System.out.println("业务处理后置通知");
return obj;
}
public Object plugin(Object target){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new MyProxy(this, target));
}
}
5 拦截接口实现类
import lombok.Data;
import java.lang.reflect.Proxy;
@Data
public class LoginInterceptor implements Interceptor {
@Override
public Object interceptor(Invocation invocation) {
System.out.println("请先输入账号密码...");
Object obj = invocation.process();
System.out.println("登录成功...");
return obj;
}
public Object plugin(Object target){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new MyProxy(this, target));
}
public static void main(String[] args){
LoginInterceptor loginInterceptor = new LoginInterceptor();
IUser iUser = new UserImpl();
iUser = (IUser) loginInterceptor.plugin(iUser);
ServiceInterceptor serviceInterceptor = new ServiceInterceptor();
iUser = (IUser) serviceInterceptor.plugin(iUser);
iUser.say();
}
}
6 运行结果:
业务处理前置通知
请先输入账号密码...
hello world
登录成功...
业务处理后置通知
1 创建拦截器链实体类,通过list集合保存拦截器:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestInterceptorChain {
Object target;
public TestInterceptorChain(Object target) {
this.target = target;
}
List list = new ArrayList();
public void addInterceptor(Interceptor interceptor){
list.add(interceptor);
}
public Object pluginAll(){
for(int i = 0; i < list.size(); i++){
target = list.get(i).plugin(target);
}
return target;
}
public List getInterceptor(){
return Collections.unmodifiableList(list);
}
public static void main(String[] args) {
IUser obj = new UserImpl();
TestInterceptorChain testInterceptorChain = new TestInterceptorChain(obj);
testInterceptorChain.addInterceptor(new LoginInterceptor());
testInterceptorChain.addInterceptor(new ServiceInterceptor());
obj = (IUser) testInterceptorChain.pluginAll();
obj.say();
}
}
2 运行结果:
业务处理前置通知
请先输入账号密码...
hello world
登录成功...
业务处理后置通知