1.AOP
概念:分离横切关注点
- 跨多个类多个组件
2.代理
- 当我们访问某个目标时,想让这个目标
- 功能更强大,但又不想改变其代码时,使用代理。
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 {
@Autowired@Qualifier("UserDao2")private UserDao userDao;//构造函数注入/*@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}*/@Overridepublic List<User> getAll() {System.out.println("GetAll");return null;
// return userDao.selectUsers(); }
public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}
2.静态代理实现相同的接口```javapackage 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.Date;import java.util.List;public class UserServiceIProxy implements UserService {@Autowired@Qualifier("userDao2")private UserService target;public UserServiceIProxy(UserService target) {this.target = target;}@Overridepublic List<User> getAll() {System.out.println(new Date() + "getAll");return target.getAll();}}
- 测试 ```java package com.jie.ssm.proxy.staticproxy;
import com.jie.ssm.service.UserService;
public class Test {
public static void main(String[] args) {//被代理的对象UserServiceImpl userService = new UserServiceImpl();UserService proxy = new UserServiceIProxy(userService);proxy.getAll();}
}
<a name="78584cd4"></a>### 2.动态代理(JDK,CGLIB)<a name="05f60999"></a>#### 1.JDK代理1.代理类实现InvocationHandler接口```javapackage com.jie.ssm.proxy.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.util.Date;/*** JDK动态代理*/public class LogHandler implements InvocationHandler {/*** 被代理对象*/private Object target;public LogHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String methodName = method.getName();System.out.println(new Date() +":"+ methodName);return method.invoke(this.target,args);}}
- invoke方法实现拦截功能,并实现代理功能,返回的
method.invoke(this.target,args)实现了目标功能- 测试类,实现不同包下不同类的代理功能
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
- 导包
<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>
- 创建拦截方法 ```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不仅可以代理接口,还可以代理类
