目录
代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
静态代理
静态代理:每个目标类都有一个代理类。
1. 新建一个接口
package cn.offcn.dao;
public interface LogDao {
public void printLog(String name);
}
2. 新建一个实现接口的目标类
package cn.offcn.dao.impl;
import cn.offcn.dao.LogDao;
public class LogDaoImpl implements LogDao {
@Override
public void printLog(String name) {
System.out.println(name);
}
}
3. 实现接口的代理类
package cn.offcn.proxy;
import cn.offcn.dao.LogDao;
public class LogProxy implements LogDao {
private LogDao logDao;
public LogProxy(LogDao logDao){
this.logDao=logDao;
}
@Override
public void printLog(String name) {
System.out.println("打开输入流");
logDao.printLog(name);
System.out.println("关闭输入流");
}
}
4. 测试
package cn.test;
import cn.offcn.dao.LogDao;
import cn.offcn.dao.impl.LogDaoImpl;
import cn.offcn.proxy.LogProxy;
import org.junit.Test;
public class LogTest {
@Test
public void writeLog(){
//1. 创建目标类对象
LogDao logDao=new LogDaoImpl();
//2. 创建代理对象
logDao=new LogProxy(logDao);
//3. 调用
logDao.printLog("请求成功");
}
}
动态代理
动态代理:在运行时动态产生代理类的对象。
利用JDK代理实现
1. 创建目标类的接口
package cn.offcn.dao;
import java.util.List;
public interface WorkerDao {
public void saveWorker(String name);
public void updateWorker(String name,int id);
public void deleteWorker(int id);
public String getWorkerById(int id);
public List<String> getWorkers();
}
2. 创建接口的实现目标类
package cn.offcn.dao.impl;
import cn.offcn.dao.WorkerDao;
import java.util.Arrays;
import java.util.List;
public class WorkerDaoImpl implements WorkerDao {
@Override
public void saveWorker(String name) {
System.out.println("保存成功");
}
@Override
public void updateWorker(String name, int id) {
System.out.println("修改成功");
}
@Override
public void deleteWorker(int id) {
System.out.println("删除成功");
}
@Override
public String getWorkerById(int id) {
List<String> names= Arrays.asList("张三","李四","王五");
return names.get(id-1);
}
@Override
public List<String> getWorkers() {
List<String> names= Arrays.asList("张三","李四","王五");
return names;
}
}
3. 创建一个代理类的工厂
package cn.offcn.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//用来生产代理类的对象
public class FactoryProxy implements InvocationHandler {
//目标类
Object targetObject;
//创建目标类的代理类的对象
public Object creatProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("创建链接");
//回调目标类方法
Object result=method.invoke(targetObject,args);
System.out.println("关闭链接");
return result;
}
}
4. 测试
package cn.test;
import cn.offcn.dao.WorkerDao;
import cn.offcn.dao.impl.WorkerDaoImpl;
import cn.offcn.proxy.FactoryProxy;
import org.junit.Test;
public class DyProxyTest {
@Test
public void testProxy(){
//1. 创建目标类对象
WorkerDao workerDao=new WorkerDaoImpl();
//2. 生产目标类的代理类对象
workerDao=(WorkerDao) new FactoryProxy().creatProxyInstance(workerDao);
workerDao.saveWorker("123");
}
}
Cglib代理实现
1. 导入cglib依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
2. 创建一个目标类
package cn.offcn.dao.impl;
public class StudentDaoImpl {
public void saveStudent(String name){
System.out.println(name+"保存成功");
}
}
3. 代理工厂
package cn.offcn.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import java.lang.reflect.Method;
public class CglibProxyFactor implements InvocationHandler {
private Object targetObject;
public Object creatProxyInstance(Object targetObject){
this.targetObject=targetObject;
//1.创建对象
Enhancer enhancer=new Enhancer();
//2.设置代理类为目标类的子类
enhancer.setSuperclass(targetObject.getClass());
//3.设置回调函数
enhancer.setCallback(this); //4.创建代理类对象
return enhancer.create();
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("准备打开链接");
//回调目标函数
Object result=method.invoke(targetObject,objects);
System.out.println("关闭链接");
return result;
}
}
4. 测试
@Test
public void testProxy02(){
//1. 创建目标类对象
StudentDaoImpl studentDao=new StudentDaoImpl();
//2. 生产目标类的代理类对象
studentDao=(StudentDaoImpl) new CglibProxyFactor().creatProxyInstance(studentDao);
studentDao.saveStudent("123");
}