JDK动态代理 使用前提有接口
1.目标类 接口+实现
2.切面类 用于存通知MyAspect
3.工厂类:用于生成代理
4.测试
目标类:
public interface UserService {
public void addUser();
public void deleteUser();
public void updateUser();
}
public class UserServiceImpl implements UserService{
@Override
public void addUser() {
// TODO Auto-generated method stub
System.out.println("增加方法");
}
@Override
public void deleteUser() {
// TODO Auto-generated method stub
System.out.println("删除方法");
}
@Override
public void updateUser() {
// TODO Auto-generated method stub
System.out.println("修改方法");
}
}
切面类:
public class MyAspect {
public void before() {
System.out.println("前置通知:在方法执行前执行");
}
public void after() {
System.out.println("后置通知:在方法执行后执行");
}
}
工厂类:
public class MyFactory {
public static UserService createService() {
//目标类
final UserService uservice=new UserServiceImpl();
//切面类
final MyAspect myAspect=new MyAspect();
//代理类 :将目标类(切点)和切面类(通知)结合--->切面
/**
* newProxyInstance(loader,interfaces,InvocationHandler)
* loader:类加载器 运行时创建 ,任何类都需要将其加载到内存
* 一般情况下:当前类.class.getClassLoader();
* 目标类实例:目标类.getClass().getClassLoader();
* interfaces:代理类需要实现的所有接口
* 方式一:目标类实例.getClass().getClassInterfaces();注意:只能获得自己的接口,不能获得父类得接口
* 方式二:new Class[]{UserService.class}
* InvocationHandler:处理类,接口,必须进行实现类一般使用匿名内部类
* 它提供了一个invoke方法,也就是说代理类的每一个方法执行时都会调用一次invoke方法
* invoke方法的三个参数:
* Object proxy:代理类对象
* Method method:代理对象当前执行方法的描述对象(反射)
* method.getName()执行方法名
* method.invoke(对象,实际参数) 执行的方法
* Object[] args:方法的实际参数
*
**/
UserService proxyService=(UserService) Proxy.newProxyInstance(
MyFactory.class.getClassLoader(),uservice.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
//前执行
myAspect.before();
//执行目标类方法
Object obj=method.invoke(uservice, args);
//后执行
myAspect.after();
return obj;
}
});
return proxyService;
}
}
测试类:
public class Test {
@org.junit.Test
public void test() {
UserService userservice=MyFactory.createService();
userservice.addUser();
userservice.deleteUser();
userservice.updateUser();
}
}
运行结果