代理模式
1、代理模式
代理对象 :对原始对象的方法做了增强
2、静态代理
2.1定义接口
//抽象主体
public interface Subject {
public String request();
}
2.2定义接口的实现类 RealSubject并实现该接口,重写方法–被代理对象
package cn.happy.proxy;
public class RealSubject implements Subject {
@Override
public String request() {
System.out.println("真实主题的操作内容");
return "呵呵";
}
}
2.3定义接口的实现类ProxySubject并实现该接口重写方法。自定义属性RealSubject,调用request方法,在这里进行增强
package cn.happy.proxy;
public class ProxySubject implements Subject {
//01.植入一个 真实主题的引用
private RealSubject real;
@Override
public String request() {
System.out.println("before execute");
real.request();
System.out.println("after execute");
return "proxy";
}
public RealSubject getReal() {
return real;
}
public void setReal(RealSubject real) {
this.real = real;
}
}
2.4测试类
//静态代理
public class Spring_01Test {
@Test
public void proxyTest(){
//准备一个真实主题,被代理对象
RealSubject real=new RealSubject();
//02.创建一个代理对象
ProxySubject proxy=new ProxySubject();
proxy.setReal(real);
proxy.request();
}
}
2.5测试结果
[外链图片转存中…(img-56LRRF9w-1588854309799)]
3、JDK动态代理
3.1定义接口IUserDao
//接口
public interface IUserDAO {
public String add();
public String edit();
}
3.2定义接口实现类,实现某接口,并重写该方法
public class UserDAOImpl implements IUserDAO {
public String add() {
//开启事务
System.out.println("add ok!");
return "add";
//logger
}
public String edit() {
//开启事务
System.out.println("edit ok!");
return "edit";
//开启事务
}
}
3.3测试类:(重点)
//jdk动态代理测试
public class MyTest {
@Test
/**
* jdk动态代理测试
*/
public void staticproxyTest(){
//01.先创建出接口实现类
final IUserDAO dao=new UserDAOImpl();
//02.类Proxy
IUserDAO proxy=(IUserDAO)Proxy //
.newProxyInstance(dao.getClass() //获取实现类的类加载器
.getClassLoader(), dao.getClass(). //
getInterfaces(), // 获取实现类接口
new InvocationHandler() { //Invocation(调用 ) Handler (处理)
/**proxy 代理对象
* method 被代理对象 方法 add()
* args add方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//code 1
System.out.println("start Tran");
//真正业务
//执行dao对象的add方法,传入的是args参数,返回值是result
Object result = method.invoke(dao, args);
//code 2
System.out.println("write logger");
return result;
}
});
String add = proxy.add();
System.out.println("======="+add+"=======");//"add"
proxy.edit();
}
}
3.4实现效果
[外链图片转存中…(img-6JmTTcHK-1588854309801)]
4、cglib动态代理
4.1 创建被代理的类
public class UserService {
public void delete(){
System.out.println("delete ok!");
}
}
4.2 测试类:(重点)
//cglib动态代理测试
public class MyTest {
@Test
/**
* cglib动态代理测试
*/
public void cglibProxyTest(){
final UserService service=new UserService();
//cglib动态代理\4\
//01.需要类 Enhancer
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(service.getClass());
enhancer.setCallback(new MethodInterceptor(){
public Object intercept(Object obj, Method method, Object[] aobj,
MethodProxy methodproxy) throws Throwable {
System.out.println("before");
method.invoke(service, aobj);
System.out.println("after");
return null;
}
});
//02.用方法
UserService proxy= (UserService)enhancer.create();
//03.
proxy.delete();
}
}
4.3 实现效果
5、静态代理、JDK代理和cglib的区别
静态代理: 简单,代理模式,是动态代理的理论基础。常见使用在代理模式
jdk动态代理 : 需要有顶层接口才能使用,但是在只有顶层接口的时候也可以使用,常见是mybatis的mapper文件是代理。
使用反射完成。使用了动态生成字节码技术。
cglib动态代理 :可以直接代理类,使用字节码技术,不能对 final类进行继承。使用了动态生成字节码技术。