JAVA动态代理是通过反射机制,创建了代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理,然后才采用具体当前接口的具体实现类的业务逻辑。
JAVA动态代理原理如下图所示:
Jdk的动态代理要求目标对象必须实现接口,因为它创建代理对象的时候是根据接口创建的。如果不实现接口,jdk无法给目标对象创建代理对象。被代理对象可以可以实现多个接口,创建代理时指定创建某个接口的代理对象就可以调用该接口定义的方法了。
示例代码:
1、定义第一个接口:
public interface Service {
public void sayHello(String name);
public int addOperter(int num,int num2);
}
2、定义第二个接口:
public interface UserService {
public void addUser(String userId, String userName) ;
public void delUser(String userId);
public void modfiyUser(String userId, String userName);
public String findUser(String userId);
}
3、定义实现类:
public class UserServiceImpl implements Service,UserService{
@Override
public void addUser(String userId, String userName) {
System.out.println("UserServiceImpl addUser userId->>"+userId);
}
@Override
public void delUser(String userId) {
System.out.println("UserServiceImpl delUser userId->>"+userId);
}
@Override
public void modfiyUser(String userId, String userName) {
System.out.println("UserServiceImpl modfiyUser userId->>"+userId);
}
@Override
public String findUser(String userId) {
System.out.println("UserServiceImpl findUser userId->>"+userId);
return "张山";
}
@Override
public void sayHello(String name) {
System.out.println("你好:"+name);
}
@Override
public int addOperter(int num, int num2) {
return num+num2;
}
}
4、编写aspect
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogHandler implements InvocationHandler {
private Object targertObject;
public Object newInstance(Object targertObject){
this.targertObject = targertObject;
Class targertClass = targertObject.getClass();
return Proxy.newProxyInstance(targertClass.getClassLoader(), targertClass.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("调用方法"+method.getName());
Object ret = null;
try {
ret = method.invoke(targertObject, args);
System.out.print("成功调用方法:"+method.getName()+";参数为:");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
} catch (Exception e) {
e.printStackTrace();
System.out.print("调用方法:"+method.getName()+"失败;参数为:");
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
}
}
return ret;
}
}
5、编写测试类:
Service Service = (Service)new LogHandler().newInstance(new UserServiceImpl());
UserService userService = (UserService)new LogHandler().newInstance(new UserServiceImpl());
userService.addUser("001", "centre");
String name = userService.findUser("002");
System.out.println(name);
int num = Service.addOperter(12, 23);
System.out.println(num);
Service.sayHello("centre");
测试结果:
调用方法addUser
UserServiceImpl addUser userId->>001
成功调用方法:addUser;参数为:001
centre
调用方法findUser
UserServiceImpl findUser userId->>002
成功调用方法:findUser;参数为:002
张山
调用方法addOperter
成功调用方法:addOperter;参数为:12
23
35
调用方法sayHello
你好:centre
成功调用方法:sayHello;参数为:centre