总述
java当中存在三种代理模式,静态代理、动态代理和cglib增强码实现的代理。其中,之前的博文中使用C++实现了代理模式的静态代理,此处就不做代码记录,需要的参照之前的实现。
前两种代理有一定的限制:需要提供接口或抽象类,才能进行实现。而最后一种则没有这个限制,直接使用实现类即可,其实现的原理是为其创建一个子类来进行功能的增强。
静态代理
参照前面代理模式中的实现。
动态代理(使用Proxy)
public class MyBeanFactory {
//功能增强类
private static final MyAspect aspect = new MyAspect();
//被代理对象类
private static final IUserService userService = new UserServiceImpl();
public static IUserService createUserService(){
//代理
IUserService proxyInstance = (IUserService) Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强的功能
aspect.before();
//原始函数的功能
Object obj = method.invoke(userService, args);
//增强的功能
aspect.after();
return obj;
}
});
return proxyInstance;
}
}
cglib实现
- 没有接口,只有实现类。
- 采用字节码增强框架 cglib,在运行时创建目标类的子类,从而对目标类进行增强。
public class MyCglibFactory {
//被代理对象类
private static final IUserService userService = new UserServiceImpl();
//功能增强类
private static final MyAspect aspect = new MyAspect();
public static IUserService createUserService(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(userService.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
aspect.before();
//第一种执行方式,需要确定的对象来进行方法调用
//Object obj = method.invoke(userService, args);
//第二种执行方式,降低了代码的耦合,不需要确定的对象(目标类和代理类的关系是父子关系)
Object obj = methodProxy.invokeSuper(proxy, args);
aspect.after();
return obj;
}
});
UserServiceImpl proxy = (UserServiceImpl) enhancer.create();
return proxy;
}
}