1.AOP

  • 概念:分离横切关注点

    • 跨多个类多个组件

2.代理

  • 当我们访问某个目标时,想让这个目标
  • 功能更强大,但又不想改变其代码时,使用代理。

1.静态代理

  1. UserServiceImpl ```java package com.jie.ssm.proxy.staticproxy;

import com.jie.ssm.dao.UserDao; import com.jie.ssm.entity.User; import com.jie.ssm.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service;

import javax.annotation.Resource; import java.util.List;

@Service public class UserServiceImpl implements UserService {

  1. @Autowired
  2. @Qualifier("UserDao2")
  3. private UserDao userDao;
  4. //构造函数注入
  5. /*@Autowired
  6. public UserServiceImpl(UserDao userDao) {
  7. this.userDao = userDao;
  8. }*/
  9. @Override
  10. public List<User> getAll() {
  11. System.out.println("GetAll");
  12. return null;

// return userDao.selectUsers(); }

  1. public void setUserDao(UserDao userDao) {
  2. this.userDao = userDao;
  3. }

}

  1. 2.
  2. 静态代理实现相同的接口
  3. ```java
  4. package com.jie.ssm.proxy.staticproxy;
  5. import com.jie.ssm.dao.UserDao;
  6. import com.jie.ssm.entity.User;
  7. import com.jie.ssm.service.UserService;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.beans.factory.annotation.Qualifier;
  10. import org.springframework.stereotype.Service;
  11. import javax.annotation.Resource;
  12. import java.util.Date;
  13. import java.util.List;
  14. public class UserServiceIProxy implements UserService {
  15. @Autowired
  16. @Qualifier("userDao2")
  17. private UserService target;
  18. public UserServiceIProxy(UserService target) {
  19. this.target = target;
  20. }
  21. @Override
  22. public List<User> getAll() {
  23. System.out.println(new Date() + "getAll");
  24. return target.getAll();
  25. }
  26. }
  1. 测试 ```java package com.jie.ssm.proxy.staticproxy;

import com.jie.ssm.service.UserService;

public class Test {

  1. public static void main(String[] args) {
  2. //被代理的对象
  3. UserServiceImpl userService = new UserServiceImpl();
  4. UserService proxy = new UserServiceIProxy(userService);
  5. proxy.getAll();
  6. }

}

  1. <a name="78584cd4"></a>
  2. ### 2.动态代理(JDK,CGLIB)
  3. <a name="05f60999"></a>
  4. #### 1.JDK代理
  5. 1.
  6. 代理类实现InvocationHandler接口
  7. ```java
  8. package com.jie.ssm.proxy.jdk;
  9. import java.lang.reflect.InvocationHandler;
  10. import java.lang.reflect.Method;
  11. import java.util.Date;
  12. /**
  13. * JDK动态代理
  14. */
  15. public class LogHandler implements InvocationHandler {
  16. /**
  17. * 被代理对象
  18. */
  19. private Object target;
  20. public LogHandler(Object target) {
  21. this.target = target;
  22. }
  23. @Override
  24. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  25. String methodName = method.getName();
  26. System.out.println(new Date() +":"+ methodName);
  27. return method.invoke(this.target,args);
  28. }
  29. }
  • invoke方法实现拦截功能,并实现代理功能,返回的method.invoke(this.target,args)实现了目标功能
    1. 测试类,实现不同包下不同类的代理功能
package com.jie.ssm.proxy.jdk;

import com.jie.ssm.dao.UserDao;
import com.jie.ssm.dao.impl.UserDaoImpl;
import com.jie.ssm.proxy.staticproxy.UserServiceImpl;
import com.jie.ssm.service.UserService;

import java.lang.reflect.Proxy;

public class JdkProxyTest {
    public static void main(String[] args) {

        p2();
    }

    public static void p1(){
        //构建被代理对象
        UserServiceImpl target = new UserServiceImpl();

        //业务增强处理器
        LogHandler handler = new LogHandler(target);

        UserService userService = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler
        );

        userService.getAll();
    }

    public static void p2(){
        //构建被代理对象
        UserDaoImpl target = new UserDaoImpl();

        //业务增强处理器
        LogHandler handler = new LogHandler(target);

        UserDao userService = (UserDao) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler
        );

        userService.selectUsers()   ;
    }
}

2.CGLIB

  • 概念:CGLIB是一个强大的、高性能的代码生成库。其被广泛应用于AOP框架(Spring、dynaop)中,用以提供方法拦截操作。Hibernate作为一个比较受欢迎的ORM框架,同样使用CGLIB来代理单端(多对一和一对一)关联(延迟提取集合使用的另一种机制)。CGLIB作为一个开源项目,其代码托管在github,地址为:https://github.com/cglib/cglib
  1. 导包
    <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <maven.compiler.source>1.7</maven.compiler.source>
     <maven.compiler.target>1.7</maven.compiler.target>
     <mybatis.version>3.5.6</mybatis.version>
     <spring.version>5.2.9.RELEASE</spring.version>
     <cglib.version>3.2.8</cglib.version>
    </properties>
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>${cglib.version}</version>
    </dependency>
    
  1. 创建拦截方法 ```java package com.jie.ssm.proxy.cglib;

import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method; import java.util.Date;

public class LogInterceptor implements MethodInterceptor {

@Override
public Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

    String methodName = method.getName();

    System.out.println(new Date()+":"+methodName);

    return methodProxy.invokeSuper(target,objects);

}

}



3. 
创建测试类
```java
package com.jie.ssm.proxy.cglib;

import com.jie.ssm.dao.UserDao;
import com.jie.ssm.dao.impl.UserDaoImpl;
import com.jie.ssm.proxy.staticproxy.UserServiceImpl;
import com.jie.ssm.service.UserService;
import net.sf.cglib.proxy.Enhancer;

public class CglibTest {
    public static void main(String[] args) {

        p2();
    }

    public static void p1(){
        //横切逻辑增强器
        //创建动态代理类,开启方法拦截
        Enhancer enhancer = new Enhancer();
        //被代理目标
        enhancer.setSuperclass(UserServiceImpl.class);
        //增强逻辑(方法拦截器    )
        enhancer.setCallback(new LogInterceptor());

        //创建代理类(接口)
        UserService userService = (UserService) enhancer.create();

        userService.getAll();
    }

    public static void p2(){
        //横切逻辑增强器
        //创建动态代理类,开启方法拦截
        Enhancer enhancer = new Enhancer();
        //被代理目标
        enhancer.setSuperclass(UserDaoImpl.class);
        //增强逻辑(方法拦截器    )
        enhancer.setCallback(new LogInterceptor());

        //创建代理类(接口)
        UserDao userService = (UserDao) enhancer.create();

        userService.selectUsers();
    }
}
  • cglib不仅可以代理接口,还可以代理类