java_Proxy动态代理_AOP
讲了JDK里使用Proxy动态代理的机制,详细过程。
切面类TransactionHandler需要实现InvocationHaandler接口,实现它的invoke方法。
项目目录:

User类代码:
package com.oracle.model;
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
UserDAO代码:
package com.oracle.dao;
import com.oracle.model.User;
public interface UserDAO {
void addUser(User u);
void deleteUser(User u);
}
UserService代码:
package com.oracle.service.impl; import com.oracle.dao.UserDAO;
import com.oracle.model.User;
import com.oracle.service.UserService; public class UserServiceImpl implements UserService{ //组合UserDAO
private UserDAO userDAO; //调用的都是UserDAO的方法
public UserServiceImpl(UserDAO userDAO) {
super();
this.userDAO = userDAO;
} @Override
public void addUser(User u) {
this.userDAO.addUser(u); } @Override
public void deleteUser(User u) {
this.userDAO.deleteUser(u); } }
UserServiceImpl代码:
package com.oracle.service.impl; import com.oracle.dao.UserDAO;
import com.oracle.model.User;
import com.oracle.service.UserService; public class UserServiceImpl implements UserService{ private UserDAO userDAO; public UserServiceImpl(UserDAO userDAO) {
super();
this.userDAO = userDAO;
} @Override
public void addUser(User u) {
this.userDAO.addUser(u); } @Override
public void deleteUser(User u) {
this.userDAO.deleteUser(u); } }
UserDAOImpl代码
package com.oracle.dao.impl; import com.oracle.dao.UserDAO;
import com.oracle.model.User; public class UserDAOImpl implements UserDAO{ @Override
public void addUser(User u) {
System.out.println("a user added !"); } @Override
public void deleteUser(User u) {
System.out.println("a user deleted !"); } }
UserAction代码:
package com.oracle.action; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import com.oracle.dao.UserDAO;
import com.oracle.dao.impl.UserDAOImpl;
import com.oracle.model.User;
import com.oracle.service.UserService;
import com.oracle.service.impl.UserServiceImpl; public class UserAction { public static void main(String[] args) { //被代理对象
UserDAO userDAO = new UserDAOImpl(); //InvocationHandler
TransactionHandler handler = new TransactionHandler(userDAO); /**
* 返回代理对象:$Proxy0
* Proxy.newProxyInstance三个参数:
* 1,要用哪个ClassLoader来产生代理对象。
* 它和被代理对象使用同一个ClassLoader,因为产生的代理对象里包含了一个被代理对象。
* 2,产生的被代理对象实现了哪些个接口:接口里有哪些方法,生成的代理就有哪些方法
* new Class[]{UserDAO.Class}多个接口时,或userDAO.getClass().getInterfaces()
* 3,当产生代理之后,当调用代理里面方法的时候,用哪一个Handler进行处理
*/
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(
userDAO.getClass().getClassLoader(),
userDAO.getClass().getInterfaces(),
handler); /**
* 代理对象的方法是怎么产生的?
* 我们的代理对象userDAOproxy里的方法有:
* 1,addUser(User u)
* 2,deleteUser(User u)
* 当代理对象里每一个方法被调用的时候,都会把它自身及参数、代理对象、传给InvocationHandler,
* 也就是我们的TransactionHandler,调用他的invoke方法
*/ /**
* 内部机制:
* Class $Proxy0 implements UserDAO{
* addUser(User u){
* Method m = UserDAO.getClass.getMethod
* handler.invoke(this,m,u);
* }
*
* }
*/ //产生的是不是UserDAO?再看他有哪些方法
//产生的类:$Proxy0 是实现了UserDAO接口了
/*System.out.println(userDAOProxy.getClass().getName());
System.out.println(userDAOProxy instanceof UserDAO);
Method[] methods = userDAOProxy.getClass().getMethods();
for(Method m: methods){
System.out.println(m.getName());
} */ UserService userService = new UserServiceImpl(userDAOProxy);
User u = new User();
u.setAge(20);
u.setName("王彦");
userService.addUser(u);
userService.deleteUser(u); }
}
TransactionHandler代码:
package com.oracle.action; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class TransactionHandler implements InvocationHandler{ private Object target; public TransactionHandler(Object target) {
super();
this.target = target;
} public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} //处理业务逻辑可以传进去Method,进行名字判断,不同的方法做不同的逻辑处理
public void beforeMethod(Method m){
//if(m.getName().equals(anObject))....做不同处理
System.out.println(m.getName()+" beginning...");
}
public void afterMethod(Method m){
System.out.println(m.getName()+" ending...");
} /**
* 三个参数:1,代理对象 2,被调用方法,3,被调用方法的参数
* 代理的哪个方法被掉用,就把代理对象、方法及参数传过来,
* 首先加自己的业务逻辑,再调用被代理对象的方法
*/ @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { beforeMethod(method);
//调用被代理对象
Object obj = method.invoke(this.target,args);
afterMethod(method);
return obj;
} }
运行结果:
addUser beginning...
a user added !
addUser ending...
deleteUser beginning...
a user deleted !
deleteUser ending...
User的addUser、deleteUser方法前后都加上了想要处理的业务逻辑,而源代码不用改变。
AOP用处:
权限、日志、审查、效率检查、异常管理。。。
java_Proxy动态代理_AOP的更多相关文章
- java动态代理_aop
(一)代理概述 1.问题:要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理.日志.计算方法的运行时间.事务管理等等,如何去做? 解答:编写一个与目标类具有相同接口的代理类 ...
- JDK动态代理
一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...
- AOP之Castle DynamicProxy 动态代理
这里主要介绍使用castle这个动态代理,在.net一些开源的框架里可以找到它的影子,就连微软的rchard也是使用这个进行方法拦截等可以基于这个进行方法拦截,在这个方面PostSharp算是比较好用 ...
- java动态代理的2种实现方式
java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...
- JDK动态代理实现原理
之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的.直到看了他的文章才彻底明白,附网址:htt ...
- java中动态代理的实现
动态代理的实现 使用的模式:代理模式. 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.类似租房的中介. 两种动态代理: (1)jdk动态代理,jdk动态代理是由Java内部的反射机制 ...
- 静态代理和利用反射形成的动态代理(JDK动态代理)
代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...
- Java动态代理
代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关 ...
- Java 动态代理机制详解
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
随机推荐
- (广搜)Dungeon Master -- poj -- 2251
链接: http://poj.org/problem?id=2251 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2137 ...
- 20155334 2016-2017-2 《Java程序设计》第六周学习总结
20155334 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第十章:输入/输出 InputStream与OutputStream java将输入/输出抽 ...
- 重拾C语言基础知识
从实习到工作两年多的时间了,虽然感觉学到了很多知识,但是事实上却将立足之本的基础知识给忘了个精光.也许跟自己没有出去找工作有关,没有好好的将C语言的基础牢牢掌握. 从现在开始吧!好好的重温基础,做一名 ...
- 设置 ssh 使用public key 免密码登录
第一步,生成自己公钥, 私钥 1: ssh-keygen -t rsa 2: 3: root@yjlml:~# ssh-keygen -t rsa 4: Generating public/pri ...
- solr介绍一:Analyzer(分析器)、Tokenizer(分词器)
首先,不知道大家在前面的例子中没有试着搜索文本串,就是在第二节,我们添加了很多文档.如果字段值是一个文本.你如果只搜索这个字段的某个单词,是不是发现搜不到? 这就是因为我们没有配置Analyzer,因 ...
- js自执行函数、调用递归函数、圆括号运算符、函数声明的提升
前言 起因是我要在jquery的ajax中需要根据返回值来决定是否继续发起ajax请求,这是一个有条件的循环,符合条件就跳出.可以使用while循环的,但是想了想还是递归调用好用. 调用递归函数 递归 ...
- EF框架下的双表查询
最近想使用ef做一些开发但是遇到了一些小问题就是如何实现多表的查询然后经过查资料终于找出了结果 我们知道ef中表的关系是一对一 一对多 多对多 接下来就讲一下一对一的关系下的栗子 先编写两个表 第 ...
- Mysql 优化与测试
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 以下的测试数据根据环境的不同所耗费的时间有所不同,例如我在腾讯云上的测试 ...
- 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)
题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...
- SpringMvc渲染视图
这篇博文讨论的问题是从ModelAndView如何渲染到页面. 首先要知道每个请求处理完之后都会返回一个ModelAndView对象. 这里我分6种情况来分析,代表6种返回类型: ModelAndVi ...