1.概念
-
代理模式: 在业务层不方便做,但是又不得不做的事情,可以放到代理对象中. 通过这样的设计就可以解决业务层耦合的问题. 代理对象看起来和真是的对象 一模一样.所以用户使用不会察觉. -
Java动态代理类位于Java.lang.reflect包下。 -
动态代理就是,在程序运行期,创建真实对象的代理对象,并对真实对象中的方法进行逻辑增强的一种技术。在生成代理对象的过程中,真实对象不变,代理对象中的方法是真实对象方法的增强方法。代理类在程序运行期间,创建的代理对象就是动态代理对象。创建的代理对象,并不是事先在Java代码中定义好的。而是在运行期间,根据我们在动态代理对象中的“指示”,动态生成的。
2.原理
- 为目标类创建代理类的字节码文件
- 使用ClassLoader将字节码文件存入JVM
- 创建代理类实例对象,执行对象的目标方法
3.Proxy.newProxyInstance
生成动态代理:
newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
ClassLoader loader —> 类加载器 读取真实的类数据 Class<?>[] interfaces —> 要求传递接口的信息 InvocationHandler h —>当代理对象执行方法时 ,调用invoke方法取执行
4.InvocationHandler
InvocationHandler:对目标类进行增强,用来处理这些增强的类, 代理类调用InvocationHandler的invoke()方法,然后执行
invoke():
- proxy:代理对象
- method:调用的方法
- args:方法中的参数
5.代码演示(Spring工程)
接口类
public interface UserService {
void addUser();
void deleteUser();
}
实现接口类
public class UserServiceImpl implements UserService{
@Override
public void addUser() {
System.out.println("完成用户新增");
}
@Override
public void deleteUser() {
System.out.println("完成用户删除");
}
配置类
@Configuration
@ComponentScan("com.jt.demo1")
public class SpringConfig {}
动态代理
public class JDKProxy {
public static Object getProxy(Object target){
ClassLoader classLoader = target.getClass().getClassLoader();
Class[] interfaces = target.getClass().getInterfaces();
return Proxy.newProxyInstance(classLoader,interfaces,getInvocationHandler(target));
}
public static InvocationHandler getInvocationHandler(Object target){
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("事物开始");
Object result = method.invoke(target, args);
System.out.println("事物提交");
return result;
}};}}
测试类
public class SpringTx {
public static void main(String[] args) {
ApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean(UserService.class);
System.out.println(userService);
UserService proxy = (UserService) JDKProxy.getProxy(userService);
System.out.println(proxy.getClass());
proxy.addUser();
proxy.deleteUser();}}
运行结果
com.jt.demo1.service.UserServiceImpl@4df50bcc
class com.sun.proxy.$Proxy9
事物开始
完成用户新增
事物提交
事物开始
完成用户删除
事物提交
|