aop学习总结一------使用jdk动态代理简单实现aop功能
2024-08-22 19:55:08
aop学习总结一------使用jdk动态代理实现aop功能
动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码
Jdk动态代理(proxy):目标对象必须实现接口,jdk的动态代理对象会默认实现目标对象的所有接口
模拟业务需求:
1.拦截所有业务方法
2.判断用户是否有权限,有权限就允许用户执行业务方法,无权限不允许用户执行业务方法
(判断是否有权限是根据user是否为null)
业务接口类:
public interface PersonService { public void save(String name);
public void update(String name,Integer personId);
public String getPersonName(Integer personId);
}
业务接口实现类:
import ql.service.PersonService; public class PersonServiceBean implements PersonService { private String user=null; public PersonServiceBean(){} public PersonServiceBean(String user){
this.user=user;
} public String getUser() {
return user;
} public void setUser(String user) {
this.user = user;
} public void save(String name) { System.out.println("我是save()方法");
} public void update(String name, Integer personId) {
System.out.println("我是update()方法");
} public String getPersonName(Integer personId) {
System.out.println("我是getPersonName()方法");
return "success";
} }
jdk代理对象工厂类:
package ql.service.aop; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import ql.service.impl.PersonServiceBean; public class JDKProxyFactory implements InvocationHandler { //目标对象
private Object targetObject; //得到一个代理实例
public Object createProxyIntance(Object targetObject){ this.targetObject=targetObject;
//第一个参数:目标对象的类装载器
//第二个参数:代理对象实现了的目标对象的接口,即目标对象的接口
//第三个参数:接口回调,使用aop拦截时会触发哪个类的拦截方法,要去拦截类必须实现InvocationHandler接口
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this);
} //被触发的拦截的方法
/**
* params:
* proxy:代理对象
* method:被拦截的方法
* args:方法的输入参数
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
PersonServiceBean bean=(PersonServiceBean) targetObject; Object result=null;
if (bean.getUser()!=null) {
//执行目标对象的方法
result=method.invoke(targetObject, args);
} return result;
} }
单元测试类:
package ql.test; import org.junit.Before;
import org.junit.Test; import ql.service.PersonService;
import ql.service.aop.JDKProxyFactory;
import ql.service.impl.PersonServiceBean; public class ProxyTest { @Before
public void setUp() throws Exception {
} @Test
public void testJDKProxyFactory1() { JDKProxyFactory factory=new JDKProxyFactory();
PersonService service=(PersonService) factory.createProxyIntance(new PersonServiceBean() );
service.save("小明");
}
@Test
public void testJDKProxyFactory2() { JDKProxyFactory factory=new JDKProxyFactory();
PersonService service=(PersonService) factory.createProxyIntance(new PersonServiceBean("xxx") );
service.save("小明");
} }
最新文章
- BSBuDeJie_04
- 【转】PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
- vi command
- jQuery取得select 选中值和文本 来自园友“大气象”
- php 环境的搭建
- Chapter 4
- socket对于大数据的发送和接收
- ContextMenuStrip控件
- Codeforces Round #261 (Div. 2) D 树状数组应用
- underscore.js 源码
- Winsock SPI-Socks5-SSL
- Swift搭建服务端
- 【朝花夕拾】Android安全之(一)权限篇
- Java GC相关知识
- Aerospike-内存和硬盘混合存储的kv数据库
- 使用node写一个简单的页面操作
- vue2.0 技巧汇总
- python 数组或列表维度增加
- LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流
- bootstrap 引用注意事项
热门文章
- 标准C程序设计七---43
- dpkg --add-architecture i386 &;&; apt-get update &;&; >; apt-get install wine32
- 驱动13.i2c设备驱动程序
- fork()函数的执行过程、孤儿进程和僵尸进程
- PHP文件函数
- php的fastcgi_finish_request()函数
- LeetCode OJ——Pascal's Triangle
- python读取Excel实例
- Java 基础【02】 Super 用法
- [WPF自定义控件库]以Button为例谈谈如何模仿Aero2主题