纵有疾风起,人生不言弃。——瓦雷里《海滨墓园》
代理模式
代理模式(Proxy)是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,比如添加权限,访问控制和审计等功能。
代理对象
1、代理对象存在的价值主要用于拦截对真实业务对象的访问。
2、代理对象应该具有和目标对象(真实业务对象)相同的方法。
代理分类
1、静态代理
2、动态代理(1、jdk动态代理和Cglib动态代理)
代码实现
说明:在之后的所有实现方式中使用的依赖都是如下
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<!--添加通配的依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>com.springsource.org.aspectj.weaver</artifactId>
<version>1.6.8.RELEASE</version>
</dependency>
首先创建一个”真实的业务“,用来代表以后真实开发的业务
service类
package com.qianfeng.aop01;
import java.util.List;
/**
* Created by Administrator on 2020/2/29.
*/
public interface IUserService<T>{
List<T> getAllUser();
boolean saveUser(T user);
boolean deleteUser(int uid);
boolean updateUser(T obj);
}
serviceimpl类
在此类中编写具体实现的功能
package com.qianfeng.aop01;
import com.qianfeng.aop01.IUserService;
import java.util.List;
/**
* Created by Administrator on 2020/2/29.
*/
public class UserServiceImpl implements IUserService {
@Override
public List getAllUser() {
System.out.println("--------getAllUser----------");
return null;
}
@Override
public boolean saveUser(Object user) {
System.out.println("--------saveUser----------");
return false;
}
@Override
public boolean deleteUser(int uid) {
System.out.println("--------deleteUser----------");
return false;
}
@Override
public boolean updateUser(Object obj) {
System.out.println("--------updateUser----------");
return false;
}
}
好,现在接下来就是aop的编写了,先自己定义一个类,在其中编写要额外添加的方法,比如
MyAspect
。
其中的两个方法分别表示了在实现真实功能之前添加的额外功能,和之后添加的功能,
package com.qianfeng.aop01;
/**
* Created by Administrator on 2020/2/29.
*/
public class MyAspect {
public void before(){
System.out.println("*****before*****");
}
public void after(){
System.out.println("*****after*****");
}
}
OK,重点代码:我们闲杂需要一个类似于工厂的类,用来将我们之前写的真实业务和额外功能整合到一起,那么创建一个类如下:
package com.qianfeng.aop01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by Administrator on 2020/2/29.
*/
public class
UserFactory {
public static IUserService getUserService() {
//创建目标对象
IUserService us = new UserServiceImpl();
MyAspect myAspect = new MyAspect();
/**
*创建一个代理对象
*使用Proxy类的静态方法newProxyInstance来对目标对象us进行代理,目的在于在us的功能之外不修改源代码的基础上增加功能
*
* 参数说明:
* UserFactory.class.getClassLoader():类加载器
* us.getClass().getInterfaces():类对象的调用的接口们
* new InvocationHandler():调用处理程序
*/
IUserService ius = (IUserService) Proxy.newProxyInstance(UserFactory.class.getClassLoader(), us.getClass().getInterfaces(), new InvocationHandler() {
/**
* 代理对象调用的回调方法
* @param proxy 代理对象
* @param method 被代理的方法
* @param args 被代理方法的参数列表
* @return 每个被代理方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在原本事情还没开始干的时候先干的额外的事情
myAspect.before();
/**
* 本来干的事情
* 对象 o 是调用方法的返回值
*/
Object o = method.invoke(us, args);
//在原本事情干完了之后干的额外的事情
myAspect.after();
return o;
}
});
return ius;
}
}
代码中添加了详细的注释,很容易看懂吧。
到现在,功能基本完成,接下来就是调用这个代理的方法了。现在可不能像之前那样直接new对象,那样用不到代理方法了。而是像这样通过代理方法来获得对象
package com.qianfeng.aop01;
import org.junit.Test;
/**
* Created by Administrator on 2020/2/29.
*/
public class TestUser {
@Test
public void testAop01() {
//代理对象
IUserService ius = UserFactory.getUserService();
ius.getAllUser();
ius.deleteUser(01);
ius.updateUser(new Object());
ius.updateUser(new Object());
}
}
这就是实现代理的方法之一。