在千锋“逆战”学习第13天,
今天学习了spring的aop动态代理
奋斗没有终点,任何时候都是一个起点;
课程作业笔记
动态代理实现的三种方式(一部分)
先建立要用到的公共类
UserService接口
import java.util.List;
public interface UserService<T> {
//查询所有用户
List<T> getUsers();
//保存用户
boolean saveUser(T t);
//删除用户
boolean deleteUser(int oid);
//修改用户
boolean updateUser(T t);
}
UserServiceImpl类
package aop1.impl;
import aop1.UserService;
import java.util.List;
public class UserServiceImpl<T> implements UserService<T> {
@Override
public List<T> getUsers() {
System.out.println("查询所有用户...");
return null;
}
@Override
public boolean saveUser(T t) {
System.out.println("存储用户...");
return true;
}
@Override
public boolean deleteUser(int oid) {
System.out.println("根据id删除用户...");
return true;
}
@Override
public boolean updateUser(T t) {
System.out.println("根据修改用户...");
return false;
}
}
User类
package aop1;
public class User {
private int id;
private String name;
private String tel;
}
UserFactor类
package aop1;
import aop1.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserFactor {
public static UserService<User> getUserService(){
//获取UserService实现类
UserService userService = new UserServiceImpl<User>();
//使用动态代理创建代理的OUserService实现类
UserService userService2 = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() {
//loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
//interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
//h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy: - 指代我们所代理的那个真实对象
//method: - 指代的是我们所要调用真实对象的某个方法的Method对象
//args: - 指代的是调用真实对象某个方法时接受的参数
Myaspect.befor(method);
Object obj = method.invoke(userService, args);
Myaspect.after(method);
return obj;
}
});
return userService2;
}
}
Myaspect切面类
package aop1;
import java.lang.reflect.Method;
public class Myaspect {
public static void befor(Method method){
System.out.println("进入"+method.getName()+"()方法");
}
public static void after(Method method){
System.out.println("离开"+method.getName()+"()方法");
}
}
测试一
import aop1.User;
import aop1.UserFactor;
import aop1.UserService;
import aop1.impl.UserServiceImpl;
import org.junit.Test;
public class Test01 {
@Test
public void getUserService(){
//先获取原生service
UserService userService = new UserServiceImpl<User>();
print(userService);
System.out.println("=========================");
//代理之后的userService对象
userService = UserFactor.getUserService();
print(userService);
String name = userService.getClass().getName();
}
public void print(UserService userService){
userService.getUsers();
userService.saveUser(new User());
userService.deleteUser(1);
userService.updateUser(new User());
}
}
运行结果
测试二
package aop2;
import aop1.Myaspect;
import aop1.User;
import aop1.UserService;
import aop1.impl.UserServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class UserFactor {
public static UserService<User> getUserService() {
//获取UserService实现类
UserService userService = new UserServiceImpl<User>();
//1、创建Enhancer对象
Enhancer enhancer = new Enhancer();
//2、设置增强类Enhancer的superClass
enhancer.setSuperclass(UserService.class);
//3、设置Enhancer对象的回调
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Myaspect.befor(method);
Object invoke = method.invoke(userService, objects);
Myaspect.after(method);
return invoke;
}
});
UserService userService2 = (UserService<User>) enhancer.create();
//4、通过enhancer对象的create()方法来得到代理
return userService2;
}
}
import aop1.User;
import aop2.UserFactor;
import aop1.UserService;
import aop1.impl.UserServiceImpl;
import org.junit.Test;
public class Test02 {
@Test
public void getUserService(){
//先获取原生service
UserService userService = new UserServiceImpl<User>();
System.out.println(userService.getClass().getName());
print(userService);
System.out.println("=========================");
//代理之后的userService对象
userService = UserFactor.getUserService();
System.out.println(userService.getClass().getName());
print(userService);
String name = userService.getClass().getName();
}
public void print(UserService userService){
userService.getUsers();
userService.saveUser(new User());
userService.deleteUser(1);
userService.updateUser(new User());
}
}
运行结果与上述一样
测试三
需要修改spring配置文件,重新编写Myaspect类
<bean id="userService" class="aop1.impl.UserServiceImpl"></bean>
<bean id="myaspect" class="aop3.Myaspect"></bean>
<!--ProxyFactoryBean代理的FactoryBean对象
包含4个属性注入
1、interfaces:接口组
2、target:目标对象,要代理的对象
3、interceptorNames:拦截对象的名称(切面类)
4、optimize:boolean类型的值:
true:强制使用cglib的动态代理
false:使用jdk代理-->
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="aop1.UserService" />
<property name="target" ref="userService" />
<property name="interceptorNames" value="myaspect" />
<property name="optimize" value="true" />
</bean>
package aop3;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;
public class Myaspect implements MethodInterceptor {
public void befor(Method method){
System.out.println("进入"+method.getName()+"()方法");
}
public void after(Method method){
System.out.println("离开"+method.getName()+"()方法");
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
befor(invocation.getMethod());
Object obj = invocation.proceed();
after(invocation.getMethod());
return obj;
}
}
测试类
import aop1.User;
import aop1.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test03 {
@Test
public void getUserService(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserService userService = context.getBean("proxy", UserService.class);
userService.getUsers();
userService.saveUser(new User());
userService.deleteUser(1);
userService.updateUser(new User());
}
}
测试结果与上述一致
三种动态代理创建类
1、java.lang.reflect.Proxy;
2、import org.springframework.cglib.proxy.Enhancer;
3、org.springframework.aop.framework.ProxyFactoryBean