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来满足的 ...
随机推荐
- canvas基础API
1.路径绘图: 把“钢笔”移动到画布的某个位置上 ctx.moveTo(x,y) 把“钢笔”连线到画布的某个位置上 ctx.lineTo(x,y) 描边路径的api ctx.stroke() 填充路径 ...
- 遇到了IE10不能登录的问题,很早就有解决方案了
1..net 2.0 的程序,请打开项目,打开vs开发环境的工具菜单下的 Package Manager Console ,中文名:程序包管理控制台,在打开的控制台中输入如下命令:Install-P ...
- CSS3 Box-sizing(盒子模型)
http://www.w3cplus.com/content/css3-box-sizing http://tantek.com/CSS/Examples/boxmodelhack.html box- ...
- .Net WebApi部署问题
在IIS上部署web api 完成后,浏览时出现了“The compiler failed with error code -2146232576.”的错误(有时会出现这个情况).主要是 我们在.Ne ...
- PostSharp 结合 log4net 自动记录日志
环境: VS 2012 PostSharp-4.1.28 (下载地址)https://visualstudiogallery.msdn.microsoft.com/a058d5d3-e654-43f ...
- ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例
HTML代码 和js 代码 @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name=&quo ...
- CSharp读取json配置文件内容
步骤 读取配置文件转换成字符串,代码如下 string contents = System.IO.File.ReadAllText("config.json"); 注意:该语句会抛 ...
- ceph 存储池PG查看和PG存放OSD位置
1. 查看PG (ceph-mon)[root@controller /]# ceph pg stat 512 pgs: 512 active+clean; 0 bytes data, 1936 MB ...
- 如何让Syncthing始终使用同一个设备ID?
设备ID(device id)是Syncthing最重要的参数之一,所有节点的发现.连接等操作,全部是基于这个设备ID!对于已经建立起来的P2P网络,保持重要节点的设备ID唯一性是非常重要的!!!!那 ...
- “全栈2019”Java异常第二十一章:finally不被执行的情况
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...