动态代理:指的就是通过一个代理对象来创建需要的业务对象,然后在这个代理对象中统一进行各种需求的处理。

  学习完Spring后会发现,Spring中的AOP(面向方面编程:Aspect Oriented Programming)是个很重要的知识点。实现AOP,我们一般采用代理的方式来实

现,这样可以减少重复代码的编写,也符合了OCP原则,即:对修改关闭,对扩展开放。其创建过程如下:

  步骤1:编写一个类实现InvocationHandler接口,例如:LogProxy类

  步骤2:在类中创建一个代理对象,例如:private Object target;

  步骤3:在类中创建一个方法来生成对象,这个方法的参数是指要代理的对象,getInstacne所返回的对象就是代理对象,例如:public static Object getInstance(Object o){ return null}

    步骤3.1:创建LogProxy对象,例如:LogProxy proxy = new LogProxy();

    步骤3.2:设置这个代理对象,例如:proxy.target = o;

    步骤3.3:通过Proxy的方法创建代理对象,第一个参数是要代理对象的classLoader,第二个参数是要代理对象实现的所有接口,第三个参数是实现类

InvocationHandler的对象,此时的result就是一个代理对象,代理的是o,例如:Object result = Proxy.newProxyInstance(o.getClass().getClassLoader(),

o.getClass().getInterfaces(), proxy);

  步骤4:当有了代理对象之后,不管这个代理对象执行什么方法,都会调用invoke方法,只要在该方法中作相应操作就可以了。

  创建该类的具体代码如下:

    

package com.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class LogProxy implements InvocationHandler {private Object target;public static Object getInstance(Object o){LogProxy proxy = new LogProxy();proxy.target=o;Object result = Proxy.newProxyInstance(o.getClass().getClassLoader(),o.getClass().getInterfaces() , proxy);return result;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Logger.info("进行了相关的操作");Object obj = method.invoke(target, args);return obj;}}

接下来就是调用该类进行注入了。首先,需要在applicationContent.xml配置文件中的bean中调用LogProxy类,并且采用工厂方法的方式,即:factory-method="getInstance"。参考代码如下:

   <bean id="userDynamicDao" class="com.proxy.LogProxy" factory-method="getInstance"><!-- 构造方法中引用userDao --><constructor-arg ref="userDao"/></bean>

如果采用annotation来注入,则直接在userService类中的setUserDao方法前面加上注解:@Resource(name="userDynamicDao") 就可以了

package com.service;import javax.annotation.Resource;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import com.dao.IUserDao;
import com.model.User;
import com.sun.xml.internal.bind.v2.runtime.Name;

@Service("userService")//业务层一般用Service
public class UserService implements IUserService {private IUserDao userDao;public void add(User user) {userDao.add(user);}public void delete(int id) {userDao.delete(id);}public IUserDao getUserDao() {return userDao;}public User load(int id) {return userDao.load(id);}@Resource(name="userDynamicDao")//采用代理来注入public void setUserDao(IUserDao userDao) {this.userDao = userDao;}}

相关的类如下:

package com.model;public class User {private int id;private String username;public User() {}public User(int id, String username) {this.id=id;this.username=username;}public int getId() {return id;}public String getUsername() {return username;}public void setId(int id) {this.id = id;}public void setUsername(String username) {this.username = username;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + "]";}
}

package com.dao;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;import com.model.User;//@Component("userDao")//等于完成了<bean id="userDao" class="com.dao.UserDao" />
@Repository("userDao")//@Repository一般用于DAO的注入
public class UserDao implements IUserDao {public void add(User user) {System.out.println("添加用户:"+user);}public void delete(int id) {System.out.println("删除id:"+id);}public User load(int id) {System.out.println("加载id:"+id);return null;}}

package com.dao;import com.model.User;public interface IUserDao {public void add(User user);public void delete(int id);public User load(int id);}

package com.proxy;import java.util.Date;public class Logger {public static void info(String info){System.out.println(new Date()+"---->"+info);}
}

package com.service;import com.model.User;public interface IUserService {public void add(User user);public void delete(int id);public User load(int id);
}

相应的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><!-- 打开Spring的Annotation支持 --><context:annotation-config/><!-- 设定Spring 去哪些包中找Annotation --><context:component-scan base-package="com"/><bean id="userDynamicDao" class="com.proxy.LogProxy" factory-method="getInstance"><!-- 构造方法中引用userDao --><constructor-arg ref="userDao"/></bean>
</beans>

转载于:https://www.cnblogs.com/misterzxy/p/3548859.html

Spring中的动态代理相关推荐

  1. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言 Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式 ...

  2. spring中AOP动态代理的两种方式

    AOP动态代理的两种方式 Spring AOP动态代理的方式(spring的AOP默认是JDK Proxy) 浅谈这两种动态代理 JDK的动态代理,需要有实现接口 动态代理--JDK Proxy ⚫ ...

  3. spring中使用动态代理(AOP)

    spring是整合了BGLIB和JDK两种动态代理 示例:使用CGLIB代理 public class MyCar {private String color = "blue";p ...

  4. Spring中的动态代理,前置通知

    AspectJ 定义了专门的表达式用于指定切入点.表达式的原型是: execution(modifiers-pattern? ret-type-pattern  declaring-type-patt ...

  5. 吃透Java中的动态代理

    动态代理在Java中是很重要的一部分,在很多框架中都会用到,如Spring中的AOP.Hadoop中的RPC等.为此在这把我对Java中的动态代理的理解分享给大家,同时写了一个模拟AOP编程的实例.( ...

  6. 服务引用代理类_在代理类中引用动态代理

    服务引用代理类 在Stackoverflow中有一个有趣的问题 ,关于Spring Bean如何获​​得对由Spring创建的代理的引用以处理事务,Spring AOP,缓存,异步流等.需要对代理的引 ...

  7. 在代理类中引用动态代理

    在Stackoverflow中有一个有趣的问题 ,关于Spring Bean如何获​​得对由Spring创建的代理的引用以处理事务,Spring AOP,缓存,异步流等.需要对代理的引用,因为如果存在 ...

  8. 深圳Java培训:Spring框架之动态代理

    深圳Java培训:Spring框架之动态代理 前言 动态代理是一种常用的设计模式,广泛应用于框架中,Spring框架的AOP特性就是应用动态代理实现的,想要理解AOP的实现原理我们就必须先理解动态代理 ...

  9. Quartz在Spring中设置动态定时任务 .

    什么是动态定时任务: 是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定).这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文 ...

最新文章

  1. 友盟分享和cocos2dx符合重复duplicate symbol 解决方案
  2. 位于/var/log目录下的20个Linux日志文件
  3. 为IP v6划分子网
  4. LeetCode 895. 最大频率栈(哈希+按频数存储)
  5. Python采集知乎小姐姐图片,打造颜颜值排行榜!
  6. c++编写手机小游戏代码_玩过自己开发的贪吃蛇吗?点这里,教你用Python写一个贪吃蛇小游戏!(附源代码)...
  7. mysql 字符串 底层_Mysql 的索引底层原理及数据结构详解
  8. Spring mvc 拦截器 配置心得
  9. java 多站点_Java 并发编程整体介绍 | 内含超多干货
  10. 平分物品价值java_网易互联网8.8笔试_第2题平分物品_自己的题解记录
  11. SpringBoot系列(4):构建一个多模块SpringBoot项目
  12. 2021年行政区划代码(含经纬度)mysql库
  13. PPT训练营-【目录页】
  14. matlab实现机器学习算法-回归分析
  15. javascrip语言精髓与编程实践pdf_C/C 编程推荐学习顺序和书籍
  16. 数据挖掘 文本分类(二)搜集中文语料库与ICTCLAS分词
  17. nock模拟服务响应_使用Node.js nock拦截HTTP请求
  18. idea和eclipse哪个更好用?为什么呢?
  19. golang 入门--定义数组的方式
  20. 新闻资讯门户类网站源码 织梦dedecms内核

热门文章

  1. 6. A Deeper Understanding of Deep Learning
  2. layui 流加载flow遇到的问题
  3. 软件测试ipad电池,ipad2020电池有问题是真的吗
  4. Linux 服务器程序规范、服务器日志、用户、进程间的关系
  5. 一文彻底搞懂静态库和动态库,显示链接和隐式链接
  6. UNIX(多线程):20---生产者消费者实例
  7. 关于valgrind的安装和内存泄露分析
  8. 给定没有重复数字的序列,将其全排列
  9. C++学习 高级编程
  10. 安卓牛客专项练习2020.12.31