动态代理

对目标对象进行增强,增强动作与目标动作分开、解耦

cglib性能较高但是费时,实用于 无需频繁创建代理对象或有实例池的代理 

 

例子

写arrayList动态代理类

final List list = new ArrayList();
List proxyInstance =
        (List) Proxy.newProxyInstance(list.getClass().getClassLoader(),
                list.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        return method.invoke(list, args);
                    }
                });
    proxyInstance.add("你好");
    System.out.println(list);

http://www.bjpowernode.com/tutorial_baseinterviewquestions/239.html

这是什么代理?

 http://www.bjpowernode.com/tutorial_baseinterviewquestions/239.html

 

JDK:基于反射、反射基于接口

精髓:拦截器InvocationHandler

代码我就不重新写一套了,实例代码这块还是比较简单的

借用大佬的分享把我的重点分享一下

 public interface PersonService {
	
	public String savePerson();
	
	public void deletePerson();
	
}
实现类
public class PersonServiceImpl implements PersonService{
 
	@Override
	public String savePerson() {
		System.out.println("添加");
		return "保存成功!";
	}
 
	@Override
	public void deletePerson() {
		System.out.println("删除");
	}
 
}

 

增强类:可以没有,去掉相关的代码即可,主要是增强的动作不一定是类的形式

public class MyTransaction {
	public void beginTransaction(){
		System.out.println("开启事务,或其他的业务 ");
	}
	public void commit(){
		System.out.println("提交事务");
	}
}

 

自定义拦截器:可添加自己的业务 

public class PersonServiceInterceptor implements InvocationHandler{
	//目标类,要执行的方法
	private Object target;
	//增强类,额外的处理
	private MyTransaction myTransaction;
	//构造函数注入目标类和增强类
	public PersonServiceInterceptor(Object target,MyTransaction myTransaction){
		this.target = target;
		this.myTransaction = myTransaction;
	}
 
	//代理类的每一个方法被调用的时候都会调用下边的这个invoke方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		this.myTransaction.beginTransaction();
		Object returnValue = method.invoke(this.target, args);
		this.myTransaction.commit();
		return returnValue;
	}
	
}

测试

public class ProxyTest {
	@Test
	public void test(){
		Object target = new PersonServiceImpl();
		MyTransaction myTransaction = new MyTransaction();
		PersonServiceInterceptor interceptor = new PersonServiceInterceptor(target, myTransaction);
              //关键,增强类可以没有,去掉相关的代码即可;拦截器一定要有
		PersonService personService = (PersonService)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),interceptor);
		String returnValue = (String)personService.savePerson();
		System.out.println(returnValue);
	}
}

 

https://www.cnblogs.com/lxcmyf/p/6433018.html

https://blog.csdn.net/ju_362204801/article/details/90714295

 

cglib:字节码技术,代理类创建子类来代理

代理对象为目标对象子类

代理的类和增强类是一样的

实现拦截器不同:

public class PersonServiceInterceptor implements MethodInterceptor{
	
	private Object target;
	
	private MyTransaction myTransaction;
	
	public PersonServiceInterceptor(Object target,MyTransaction myTransaction){
		this.target = target;
		this.myTransaction = myTransaction;
	}
	//利用增强器创建代理,
	public Object createProxy(){
		Enhancer enhancer = new Enhancer();
		enhancer.setCallback(this);
		enhancer.setSuperclass(this.target.getClass());
		return enhancer.create();
	}
 
	@Override
	public Object intercept(Object object, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {
		myTransaction.beginTransaction();
		Object returnValue = method.invoke(this.target, args);
		myTransaction.commit();
		return returnValue;
	}
	
}

测试:
public class ProxyTest {
	@Test
	public void test(){
		Object target = new PersonServiceImpl();
		MyTransaction myTransaction = new MyTransaction();
		PersonServiceInterceptor interceptor = new PersonServiceInterceptor(target, myTransaction);
		PersonService personService =(PersonService) interceptor.createProxy();
		String returnValue = (String)personService.savePerson();
		System.out.println(returnValue);
	}
}

也可以把增强器拿出来:

public class Landlord {
    public void rent(){
        System.out.println("房东要出租房子了!");
    }
}

public class Intermediary implements MethodInterceptor {

    @Override
    public Object intercept(Object object, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {
        Object intercept = methodProxy.invokeSuper(object, args);
        System.out.println("中介:该房源已发布!");
        return intercept;
    }
}

public class Test {
    public static void main(String[] args) {
        Intermediary intermediary = new Intermediary();
        
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(Landlord.class);
        enhancer.setCallback(intermediary);
        
        Landlord rentProxy = (Landlord) enhancer.create();
        rentProxy.rent();
    }
}

 

说到代理不得不提AOP,原因你懂的

springaop 代理类 增强类不需要自己实现,配置文件配置或使用注解,spring会帮你生成代理对象,上面的两种代理spring据情况不同对应生成代理对象

可喜的是aop简单易懂

 

https://blog.csdn.net/qq_39470733/article/details/77315010?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

 

https://www.baidu.com/s?wd=%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F&rsv_spt=1&rsv_iqid=0x948d420f000248ca&issp=1&f=3&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ts_0&rsv_sug3=17&rsv_sug1=24&rsv_sug7=101&rsv_sug2=1&rsv_btype=i&prefixsug=%25E5%258A%25A8%25E6%2580%2581%25E4%25BB%25A3%25E7%2590%2586%25E3%2580%2591&rsp=0&inputT=9629&rsv_sug4=9629

 

https://baijiahao.baidu.com/s?id=1628782377871648532&wfr=spider&for=pc

你可能感兴趣的:(动态代理)