[关闭]
@BertLee 2017-08-10T11:26:13.000000Z 字数 3193 阅读 1241

改头换面的代理模式

序言

  代理模式可以实现对被代理对象的间接控制,可以对被代理对象的方法进行增强,她不重写原有的方法。
代理模式基本分为3类:

  1. jdk静态代理: 1个代理类只能代理1个类,局限性较大。
  2. jdk动态代理: 1个代理类能代理多个类,要求被代理类必须要有接口,利用了反射,效率比较低。
  3. cglib动态代理:1个代理类能代理多个类,被代理类不需要有接口,效率较高,不能代理final的类和方法

1. jdk静态代理模式

套路:
1. 代理类要实现被代理类的接口,使代理类的方法与被代理类的保持一致。
2. 代理类要加入一个被代理类的委托对象,由客户端初始化。
3. 添加私有的增强方法。

  1. /**
  2. * 登录接口
  3. */
  4. public interface LoginService {
  5. public void login();
  6. }
  1. /**
  2. * 登录接口代理对象
  3. */
  4. public class LoginServiceProxy implements LoginService{
  5. private LoginService loginService;
  6. public LoginServiceProxy(LoginService loginService){
  7. this.loginService = loginService;
  8. }
  9. public void login() {
  10. preLogin();
  11. loginService.login();
  12. postLogin();
  13. }
  14. private void preLogin(){
  15. System.out.println("=====登录前认证校验=====");
  16. }
  17. private void postLogin(){
  18. System.out.println("=====登录后日志记录=====");
  19. }
  20. }
  1. /**
  2. * 登录接口实现类
  3. */
  4. public class LoginServiceImpl implements LoginService{
  5. public void login() {
  6. System.out.println("正在登录...");
  7. }
  8. }
  1. /**
  2. * jdk静态代理测试
  3. */
  4. public class JdkStaticProxyTest {
  5. @Test
  6. public void testJdkStaticProxy(){
  7. LoginServiceProxy loginServiceProxy = new LoginServiceProxy(new LoginServiceImpl());
  8. loginServiceProxy.login();
  9. }
  10. }

2. jdk动态代理模式

  1. /**
  2. * 登录接口
  3. */
  4. public interface LoginService {
  5. public void login();
  6. }
  1. /**
  2. * 登录接口实现类
  3. */
  4. public class LoginServiceImpl implements LoginService {
  5. public void login() {
  6. System.out.println("正在登录...");
  7. }
  8. }
  1. /**
  2. * 登录接口代理对象
  3. */
  4. public class ServiceInvocationHandler implements InvocationHandler {
  5. //被代理对象
  6. private Object target;
  7. public ServiceInvocationHandler(Object object){
  8. this.target = object;
  9. }
  10. private void preOperation(){
  11. System.out.println("=====执行前校验=====");
  12. }
  13. private void postOperation(){
  14. System.out.println("=====执行后记录日志=====");
  15. }
  16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17. preOperation();
  18. Object result = method.invoke(target, args);
  19. postOperation();
  20. return result;
  21. }
  22. public Object getProxy() throws Throwable {
  23. return Proxy.newProxyInstance(Thread.currentThread()
  24. .getContextClassLoader(), this.target.getClass()
  25. .getInterfaces(), this);
  26. }
  27. }
  1. /**
  2. * jdk静态代理测试
  3. */
  4. public class JdkDynamicProxyTest {
  5. @Test
  6. public void testJdkStaticProxy() throws Throwable {
  7. LoginService proxy = (LoginService) new ServiceInvocationHandler(new LoginServiceImpl()).getProxy();
  8. proxy.login();
  9. System.out.println(proxy.getClass());
  10. }
  11. }

3. cglib动态代理模式

  1. /**
  2. * 登录类
  3. */
  4. public class LoginServiceImpl{
  5. public void login() {
  6. System.out.println("正在登录...");
  7. }
  8. }
  1. /**
  2. * 登录接口代理对象
  3. */
  4. public class LoginServiceProxy implements MethodInterceptor{
  5. private Object target;
  6. public LoginServiceProxy(Object obj){
  7. this.target = obj;
  8. }
  9. public Object getInstance(){
  10. Enhancer enhancer = new Enhancer();
  11. enhancer.setSuperclass(this.target.getClass());
  12. enhancer.setCallback(this); //设置回调方法
  13. return enhancer.create(); //创建代理对象
  14. }
  15. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  16. preOpteration();
  17. Object result = methodProxy.invokeSuper(o, objects);
  18. postOpteration();
  19. return result;
  20. }
  21. private void preOpteration(){
  22. System.out.println("=====执行前校验=====");
  23. }
  24. private void postOpteration(){
  25. System.out.println("=====执行后记录日志=====");
  26. }
  27. }
  1. /**
  2. * cglib动态代理测试
  3. */
  4. public class CglibProxyTest {
  5. @Test
  6. public void testCglibProxy(){
  7. LoginServiceImpl loginServiceProxy = (LoginServiceImpl) new LoginServiceProxy(new LoginServiceImpl()).getInstance();
  8. loginServiceProxy.login();
  9. }
  10. }

后记

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注