AOP代理模式
代理模式:Proxy或Surrogate,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。
客户端----->代理对象(代理主题)---->目标对象(真实主题)
首先创建一个接口
public interface Singer {
//唱歌
public void singing();
//跳舞
public void dancing();
}
接着创建两个目标对象,继承接口
/**
* 目标对象
*/
public class WangBaoQiang implements Singer {
@Override
public void singing() {
System.out.println("王宝强正在唱歌!");
}
@Override
public void dancing() {
System.out.println("王宝强正在跳舞!");
}
}
/**
* 目标对象
*/
public class XueZhiQian implements Singer {
@Override
public void singing() {
System.out.println("薛之谦正在唱歌");
}
@Override
public void dancing() {
System.out.println("薛之谦正在跳舞");
}
}
第一种:静态代理(扩展性差,每次生成只要有不同的目标对象,即使操作一样,也要重新生成代理对象)
/**
* 代理对象
* 首先这个代理对象也要实现接口
* 然后调用目标对象方法
*/
public class ProxyWang implements Singer{
private Singer singer;
public ProxyWang(Singer singer) {
this.singer = singer;
}
@Override
public void singing() {
System.out.println("话筒已经调试成功!");
singer.singing();
}
@Override
public void dancing() {
System.out.println("舞台已经搭建成功!");
singer.dancing();
}
}
测试
//首先实例化我们的目标对象
Singer singer = new WangBaoQiang();
//实例化代理对象来调用其方法(在调用目标对象的前后做一些相关操作)
ProxyWang proxyWang = new ProxyWang(singer);
proxyWang.singing();
第二种:动态代理(利用JAVA的反射来实现)
/**
* 实现动态代理 JDK
*/
public class ProxyAi implements InvocationHandler {
private Object object;
public ProxyAi(Object object) {
this.object=object;
}
/**
* 只要调用目标对象的方法都要执行此方法
* @param proxy 代理对象
* @param method 调用目标对象的方法(通过反射实现)
* @param args 调用目标对象的方法里的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = null;
//通过反射来调用目标对象的方法
//第一个参数是要调用目标对象方法的类
//第二个参数是目标对象方法的参数
// System.out.println("舞台搭建完毕!");
//o = method.invoke(object, args);
if (method.getName().equals("singing")){
System.out.println("话筒调试完毕!");
o=method.invoke(object,args);
System.out.println("唱歌结束!");
}else if (method.getName().equals("dancing")){
System.out.println("舞台搭建成功!");
o=method.invoke(object,args);
System.out.println("演出结束!");
}
return o;
}
}
测试
Singer singer = new WangBaoQiang();
/**
* 参数:类加载器,目标对象的Class,代理对象
* 返回值类型:Object*/
Singer singer1=(Singer) Proxy.newProxyInstance(singer.getClass().getClassLoader(),new Class[]{Singer.class
},new ProxyAi(singer));
singer1.singing();
第三种:cglibProxy代理
①引入架包
②写CglibProxy类(继承MethodInterceptor)
public class CglibProxy implements MethodInterceptor {
//实例化目标对象
private Object object;
//为了得到代理对象
public Object getCglibProxy(Object object){
this.object=object;
//得到创建代理对象的对象
Enhancer enhancer = new Enhancer();
//设置类加载器
enhancer.setClassLoader(this.object.getClass().getClassLoader());
//设置其父类
enhancer.setSuperclass(this.object.getClass());
//设置回调,只要走下面这个方法都会走回调
enhancer.setCallback(this);
//创建代理对象
return enhancer.create();
}
/**
* 方法拦截器(调用目标对象的方法都会执行这个方法)
* @param o 代理对象
* @param method 目标对象的方法
* @param objects 目标对象的方法参数
* @param methodProxy 代理对象拦截方法的对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("舞台搭建成功!");
Object ob = method.invoke(object, objects);
return ob;
}
}
测试
//实例化一个cglibProxy代理对象这个类
CglibProxy cglibProxy = new CglibProxy();
Singer singer2 =(Singer) cglibProxy.getCglibProxy(new WangBaoQiang());
singer2.singing();