Spring aop 面向切面进行开发,实现的原理就是使用动态代理设计模式,这也是spring框架的一个核心。目标对象不愿意做的事,让代理来实现。
举例:经纪人和艺人的关系,经纪人便是代理,艺人就是目标用户,艺人不想做的(安装设备,舞台等),由经纪人去联系处理,这样的模式就是代理模式。
Jdk:静态代理 动态代理 cglib 生成的动态代理
- 静态代理的缺点:扩展性差,每次生成只要有不同的目标对象,即使操作的一样,也要重新生成一个代理对象
- 优点:好理解,代码看起来不复杂
定义一个接口
package com.offcn.test;
public interface Singer {
public void singing();
public void dancing();
}
实现接口
package com.offcn.test;
public class WangBaoQiang implements Singer{
@Override
public void singing() {
System.out.println("正在唱歌");
}
@Override
public void dancing() {
System.out.println("正在跳舞");
}
}
静态代理
package com.offcn.test;
/**
*代理对象
* 首先代理对象也要实现我们的接口
* 也要调用我们王宝强(目标对象的方法)
*/
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();
}
}
动态代理
package com.offcn.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 实现动态代理 jdk
*/
public class ProxyAi implements InvocationHandler {
//目标对象
private Object object;
public ProxyAi(Object object) {
this.object = object;
}
//只要你调用目标对象的方法都会走这个方法
//第一个参数是你的代理对象,第二个参数是你调用目标对象的方法(通过反射来实现)
//第三个参数是你调用目标对象的方法里的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = null;
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;
}
}
cglib 生成的动态代理
package com.offcn.test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
//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();
}
//这个方法就是在你调用目标对象的方法都会执行这个方法
//第一个参数是代理对象,第二个参数是目标对象的方法,第三个参数是目标对象的方法参数,第四个对象是你的代理对象拦截方法的对象
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object ob = method.invoke(object, objects);
return null;
}
}
测试类
package com.offcn.test;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
//首先实例化的对象是王宝强(也就是我们的目标对象)
//Singer singer = new WangBaoQiang();
//实例化代理对象来调用其方法(在调用目标对象的前后做一些相关的操作 )
/* ProxyWang proxyWang = new ProxyWang(singer);
proxyWang.singing();*/
/*-----------------动态代理------------------------*/
//需要一个目标对象
//Singer singer = new WangBaoQiang();
Singer singer = new XueZhiQian();
//jdk提供了这样一个类,代表代理的意思
//第一个参数叫做类加载器,第二个参数是目标对象的.class
//第三个参数也就是代理对象
/* Singer singer1 = (Singer) Proxy.newProxyInstance(singer.getClass().getClassLoader(), new Class[]{Singer.class},
new ProxyAi(singer));
singer1.singing();*/
//ProxyAi proxyAi = new ProxyAi(singer);
//实例化一个cglibProxy 代理对象这个类
CglibProxy cglibProxy = new CglibProxy();
Singer singer1 = new WangBaoQiang();
//这个参数代表我们的目标对象
Singer singer2 = (Singer) cglibProxy.getCglibProxy(singer1);
singer2.singing();
}
}