代理模式
23中(Gof)中代理模式中的一种,AOP本身就是基于动态代理实现的,所以掌握了代理模式对AOP的学习很有帮助,所以先讲下代理模式
1.静态代理模式
若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和目标类会实现同一接口或是派生自相同的父类。
1.1 创建接口
/**
* 定义公共接口
* @author dpb[波波烤鸭]
*
*/
public interface SomeService {
String doSome();
}
1.2 创建接口实现类
/**
* 静态代理模式的实现类
* @author dpb[波波烤鸭]
*
*/
public class SomeServiceImpl implements SomeService{
@Override
public String doSome() {
// TODO Auto-generated method stub
return "hello";
}
}
1.3 创建静态代理类
/**
* 代理类
* 增强实现类
* 和实现类实现同一个接口
* @author dpb[波波烤鸭]
*
*/
public class SomeProxy implements SomeService{
private SomeService target;
public SomeProxy(SomeService target) {
super();
this.target = target;
}
/**
* 增强方法
* 将返回结果转换为大写
*/
@Override
public String doSome() {
return target.doSome().toUpperCase();
}
}
1.4 测试实现
public static void main(String[] args) {
SomeService some = new SomeServiceImpl();
// 获取静态代理对象
SomeProxy proxy = new SomeProxy(some);
System.out.println(proxy.doSome());
}
2.动态代理模式
代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。
代理类型 | 使用场景 |
---|---|
JDK动态代理 | 如果目标对象实现了接口,采用JDK的动态代理 |
cglib动态代理 | 如果目标对象没有实现了接口,必须采用CGLIB动态代理 |
2.1.JDK动态代理
声明接口
/**
* 定义公共接口
* @author dpb[波波烤鸭]
*
*/
public interface SomeService {
String doSome();
}
创建实现类
/**
* 静态代理模式的实现类
* @author dpb[波波烤鸭]
*
*/
public class SomeServiceImpl implements SomeService{
@Override
public String doSome() {
// TODO Auto-generated method stub
return "hello";
}
}
JDK代理实现
public static void main(String[] args) {
SomeService some = new SomeServiceImpl();
// 获取静态代理对象
SomeService proxy = (SomeService) Proxy.newProxyInstance(
some.getClass().getClassLoader() // 实现类的类加载器
, some.getClass().getInterfaces() // 实现类 实现的所有的接口
, new InvocationHandler() // 处理器
{
/**
* proxy 代理对象
* method 目标的方法
* args 目标方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String msg = (String) method.invoke(some, args);
return msg.toUpperCase();
}
});
System.out.println(proxy.doSome());
}
2.2CGLIB动态代理
导入cglib的jar包
创建目标类
/**
* 静态代理模式的实现类
* @author dpb[波波烤鸭]
*
*/
public class SomeServiceImpl {
public String doSome() {
// TODO Auto-generated method stub
return "hello";
}
}
创建cglib工厂
/**
* cglib代理类
* @author dpb[波波烤鸭]
*
*/
public class CglibProxy implements MethodInterceptor{
private SomeServiceImpl target;
public CglibProxy(SomeServiceImpl target) {
this.target = target;
}
/**
* 创建cglib代理对象的方法
* @return
*/
public SomeServiceImpl createProxy(){
// 创建增强器
Enhancer e = new Enhancer();
// 指定父类
e.setSuperclass(SomeServiceImpl.class);
// 指定回调接口对象
e.setCallback(this);
// 创建cglib代理对象
return (SomeServiceImpl) e.create();
}
/**
* 拦截方法
*/
@Override
public Object intercept(Object obj, Method method, Object[] agrs, MethodProxy proxy) throws Throwable {
String msg = (String)method.invoke(target, agrs);
return msg.toUpperCase();
}
}
测试
public static void main(String[] args) {
// 定义目标对象
SomeServiceImpl some = new SomeServiceImpl();
// 获取代理对象
SomeServiceImpl proxy = new CglibProxy(some).createProxy();
System.out.println(proxy.doSome());
}