代理对象的作用:完成原有功能的同时,借助代理对象添加额外的功能
代理:
- 目标类(target):被代理的类(对象) 真正的业务逻辑实现
- 代理类(proxy):添加额外的功能的类(对象)
开发原则:
- 代理类和目标类必须实现统一接口
- 代理类依赖于目标类
静态代理:
1.在程序运行之前手动为目标对象创建代理对象
2.静态代理存在的问题
- ① 代码量加大,增加工作量
- ② 解决方案:使用动态代理
以下为-开发静态代理类-配置静态代理类-最后通过调用静态代理类完成功能
手动实现动态代理:
- 在程序运行时,动态的创建代理对象
package test;
import org.junit.Test;
import service.AdminService;
import service.AdminServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy {
/*
* 动态代理
* 原则:
* 1. 目标类和代理类实现相同的接口
* 2. 代理类依赖于目标类
* 概念:
* 程序运行过程中, 通过jdk→Proxy类, 动态为目标类创建代理类
* */
@Test
public void test() {
//1. 创建目标类
final AdminService adminService = new AdminServiceImpl();
//2. 创建代理对象
/*
* Proxy.newProxyInstance() 返回值为代理对象
* classLoader : 类加载器(加载目标类--->读取目标类的信息)
* 1. 当前线程类加载器 Thread.currentThread().getContextClassLoader()
* 2. 当前类类加载 this.getClass().getClassLoader()
* 3. 目标类类加载器 adminService.getClass().getClassLoader()
* interfaces : 实现的接口(和目标类实现同一个接口)
* {AdminService.class}
* adminService.getClass().getInterfaces()
*
* new InvocationHandler(): 代理对象调用方法时, 优先执行回调对象的invoke()
* */
ClassLoader classLoader = adminService.getClass().getClassLoader();
Class[] interfaces = {AdminService.class};
AdminService adminServiceProxy = (AdminService) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
// 相当于自己开发的静态代理中所写的代码(额外功能, 目标方法)
/*
* 参数1 proxy: 当前代理对象
* 参数2 method: 当前代理对象调用方法的方法对象
* 参数3 args: 当前代理对象调用方法的参数
*
* "方法名: "+method.getName()
*"参数: "+args[0]
* */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 额外的功能 调用目标方法
/*
* 参数1: 执行哪个类中的方法
* 参数2: 执行哪个类中的方法携带的参数
* */
Object invoke = null;
try {
System.out.println("---开启事务---");
invoke = method.invoke(adminService, args);
System.out.println("---事务提交---");
} catch (Exception e) {
System.out.println("---事务回滚---");
e.printStackTrace();
}
return invoke;
}
});
String name = adminServiceProxy.find("张三");
System.out.println(adminServiceProxy.getClass());//动态代理对象 class com.sun.proxy.$Proxy2
}
}
service代码
package service;
public interface AdminService {
public String find(String name);
public void add();
public void update();
public void delete();
}
package service;
import dao.AdviceDaoImpl;
public class AdminServiceImpl implements AdminService {
/*
* 业务逻辑对象 负责处理业务逻辑, 调配用dao
* 代理对象 完成事务控制
*
* */
@Override
public String find(String name) {
System.out.println("调用dao find...");
throw new RuntimeException("出现异常");
/* return name;*/
}
@Override
public void add() {
System.out.println("调用dao add...");
}
@Override
public void update() {
System.out.println("调用dao update...");
}
@Override
public void delete() {
System.out.println("调用dao delete...");
}
public void setAdviceDao(AdviceDaoImpl adviceDao) {
}
}
dao代码
package dao;
public interface AdviceDao {
String find(String name);
void add();
}
package dao;
public class AdviceDaoImpl implements AdviceDao {
@Override
public String find(String name) {
System.out.println("通知dao-find");
return null;
}
@Override
public void add() {
System.out.println("通知add-find");
}
}
xml配置
<!-- 管理业务逻辑对象(serviceImpl) -->
<bean class="service.AdminServiceImpl" id="adminService"/>
<!-- 管理代理对象 -->
<bean class="proxy.AdminServiceImplProxy" id="adminServiceImplProxy">
<property name="adminService" ref="adminService"/>
</bean>
引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.26.RELEASE</version>
</dependency>