讲了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的更多相关文章

  1. java动态代理_aop

    (一)代理概述 1.问题:要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理.日志.计算方法的运行时间.事务管理等等,如何去做? 解答:编写一个与目标类具有相同接口的代理类 ...

  2. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  3. AOP之Castle DynamicProxy 动态代理

    这里主要介绍使用castle这个动态代理,在.net一些开源的框架里可以找到它的影子,就连微软的rchard也是使用这个进行方法拦截等可以基于这个进行方法拦截,在这个方面PostSharp算是比较好用 ...

  4. java动态代理的2种实现方式

    java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...

  5. JDK动态代理实现原理

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的.直到看了他的文章才彻底明白,附网址:htt ...

  6. java中动态代理的实现

    动态代理的实现 使用的模式:代理模式. 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.类似租房的中介. 两种动态代理: (1)jdk动态代理,jdk动态代理是由Java内部的反射机制 ...

  7. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  8. Java动态代理

    代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关 ...

  9. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

随机推荐

  1. IntricCondition和expliciteCondition比较

    IntricCondition 和 expliciteCondition 的区别 与 intrinsicLoc和expliciteLock的区别很相似, expliciteCondition提供了更多 ...

  2. 笔记01 登录、常用配置参数、Action访问Servlet API 和设置Action中对象的值、命名空间和乱码处理、Action中包含多个方法如何调用

    Struts2登录 1. 需要注意:Struts2需要运行在JRE1.5及以上版本 2. 在web.xml配置文件中,配置StrutsPrepareAndExecuteFilter或FilterDis ...

  3. Python学习-9.Python函数定义

    先定义一个最基本的函数作为例子: def Print(msg): print(msg) 函数名为Print,参数有一个,为msg,函数体调用print系统函数,输出msg. 接下来就是可变参数,这个特 ...

  4. MSP430 G2553 计时/计数器 Timer_A

    MSP430G2553包含了两个16-bit Timer_A计时/计数器.本文简单介绍了Timer_A的功能和寄存器使用,本文及后续的随笔部分参考了"Scientific Instrumen ...

  5. 【转载】45个设计师们不常见的html5和css3漂亮模板

    对于Web开发人员来说,当他们需要创建一个非常时尚和新潮的CSS3和HTML5网站时需要非常专业的水准.html5和css3的结合能够做出非同寻常的网站效果..所以,今天,我推荐给大家45个免费的时尚 ...

  6. Jenkins+.Net Core+Git集成发布 - SkyMallCore快速开发平台

    准备工作:安装 Jenkins+java 直接百度安装,在此忽略 dotnet sdk(iis部署已经安装) 一:windows 部署到IIS 首先搭建IIS,站点应用程序池选择 ‘无托管代码’ 安装 ...

  7. Atom打造优雅的MarkDown 编辑器

    1.下载Atom https://atom.io/ 2.安装Atom 双击自动安装,会默认安装到C盘,无法修改. 3.安装simplified-chinese-menu 插件 这是一个可以将软件汉化的 ...

  8. JS DOM对象控制HTML元素详解

    JS DOM对象控制HTML元素详解 方法: getElementsByName()  获取name getElementsByTagName()  获取元素 getAttribute()  获取元素 ...

  9. [mvc]记一次“项目”的历程

    大二上半学期因为选修课的原因,答应帮老师完善学院的选课系统.在这之前没有做过一个可以成为“项目”的项目,本着挑战自己的原则和可以不上选修课的福利,断断续续用了一学期的时间来完善这个选课系统. 接受这个 ...

  10. iOS NSMutableArray "removeObjectIdenticalTo" vs "removeObject"

    NSMutableArray 有多种可以删除元素的方法. 其中 removeObject,removeObjectIdenticalTo 这两个方法是有区别的. [anArray removeObje ...