代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。
在业务中使用代理,一般是为了给需要实现的方法添加预处理或者添加后续操作,但是不干预实现类的正常业务,把一些基本业务和主要的业务逻辑分离。
接口:UserService
public interface UserService {
void save();
}
被代理类:UserServiceImpl
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("保存用户!");
}
}
输出:
打开事务!
保存用户!
提交事务!
静态代理
创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。
代理类:UserServiceProxy
public class UserServiceProxy implements UserService{
private UserService userService;
@Override
public UserServiceProxy(UserService userService){
this.userService = userService;
}
public void save() {
System.out.println("打开事务!" );
userService.sayHello();
System.out.println("提交事务!");
}
}
代理类调用:
被代理类被传递给了代理类UserServiceProxy,代理类在执行具体方法时通过所持用的被代理类完成调用。
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService userServiceProxy = new UserServiceProxy(userService);
userServiceProxy.sayHello();
}
动态代理
目前java动态代理的实现分为两种
1.基于JDK的动态代理
2.基于CGLIB的动态代理
基于JDK的动态代理
代理对象与被代理对象实现了相同的接口
代理对象 与 被代理对象没有继承关系
基于JDK的动态代理就需要知道两个类:1.InvocationHandler(接口)、2.Proxy(类)
还要知道JDK是基于接口的动态代理,也就是说,被代理的类必须要有实现的接口才能使用JDK的动态代理。
下面我们实际用代码来讲解这两个类的实际作用:
代理类:
public class UserServiceProxyFactory implements InvocationHandler {
private UserService us;
public UserServiceProxyFactory(UserService us) {
super();
this.us = us;
}
public UserService getUserServiceProxy(){
//生成动态代理
UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(),
this);
return usProxy;//返回
}
@Override
public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
System.out.println("打开事务!");
Object invoke = method.invoke(us, arg2);
System.out.println("提交事务!");
return invoke;
}
}
代理类调用:
@Test
//动态代理
public void fun1(){
UserService us = new UserServiceImpl();
UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
}
输出:
打开事务!
保存用户!
提交事务!
CGLIB代理
CGLIB代理原理是代理对象继承被代理对象,因此被代理对象的方法不能用final修饰。
代理类:
public class UserServiceProxyFactory2 implements MethodInterceptor {
public UserService getUserServiceProxy(){
Enhancer en = new Enhancer();//帮我们生成代理对象
en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
en.setCallback(this);//代理要做什么
UserService us = (UserService) en.create();//创建代理对象
return us;
}
@Override
public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
//打开事务
System.out.println("打开事务!");
//调用原有方法
Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
//提交事务
System.out.println("提交事务!");
return returnValue;
}
}
代理类调用:
@Test
public void fun2(){
UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
}
输出:
打开事务!
保存用户!
提交事务!
Comments | NOTHING