Spring02-AOP
1,动态代理,指的是通过一个代理对象创建需要的业务对象,然后在这个代理对象中统一进行各种操作。
步骤:
1)写一个类实现InvocationHandler接口;
2)创建要代理的对象
2,创建一个简单的打印日志的类Logger
package com.yangw.spring.proxy; import java.util.Date; public class Logger { public static void info(String msg){ System.out.println(new Date()+"----"+msg); } }
3,自定义注解类
package com.yangw.spring.model; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface LogInfo { public String value() default ""; }
4,自定义动态代理类LogProxy
package com.yangw.spring.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.yangw.spring.model.LogInfo; /** * 1 写一个类,实现InvocationHandler接口 * @author Administrator * */ public class LogProxy implements InvocationHandler { //2,创建代理对象 private Object target; private LogProxy(){}; //3,创建一个方法来生成代理对象,这个方法的参数是要代理的对象 public static Object getInstance(Object obj){ //3.1 创建LogProxy对象 LogProxy proxy=new LogProxy(); //3.2 设置代理对象 proxy.target=obj; //3.3 通过Proxy.newProxyInstance()创建代理对象 //参数1:要代理对象的classloader,参数2:要代理对象的实现的所有接口, //参数3:实现InvocationHandler接口的对象 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), proxy); } /** * 当有了代理对象之后,都会调用下面的invoke()方法 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //这里怎么处理完全由我们来控制的 /*if(method.getName().equals("add")|| method.getName().equals("delete")){ Logger.info("调用我..."); }*/ //只对有LogInfo注解的进行处理, //而且是在method.invoke调用之前,调用之后执行都可以 //在异常中进行处理也可以 if(method.isAnnotationPresent(LogInfo.class)){ Logger.info(method.getAnnotation(LogInfo.class).value()); } return method.invoke(target, args); //aspect orient program (面向切面编程) } }
5,在需要加入注解的接口上面加入自定义注解LogInfo
package com.yangw.spring.dao; import com.yangw.spring.model.LogInfo; import com.yangw.spring.model.User; public interface IUserDao { @LogInfo("add a user") public void add(User user) ; @LogInfo("delete a user") public void delete(int id) ; public User load(int id); }
6,beans2.xml中的配置如下
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!--1, 打开Spring的annotation --> <context:annotation-config/> <!-- 2, 设定Spring去那些包中找annotation --> <context:component-scan base-package="com.yangw.spring" /> <!--用代理类实现 对于静态(static)的注入,使用factory-method --> <bean id="userDynamicDao" class="com.yangw.spring.proxy.LogProxy" factory-method="getInstance"> <!--静态方法传入的参数 --> <constructor-arg ref="userDao" /> </bean> <!-- 依次加入想加入的 <bean id="msgDynamicDao" class="com.yangw.spring.proxy.LogProxy" factory-method="getInstance"> <constructor-arg ref="MsgDao" /> </bean> --> </beans>
7,UserService类上注入userDynamicDao
package com.yangw.spring.service; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.yangw.spring.dao.IUserDao; import com.yangw.spring.model.User; @Service("userService") public class UserService implements IUserService { @Resource(name="userDynamicDao") private IUserDao userDao ; @Override public void add(User user) { userDao.add(user); } @Override public void delete(int id) { userDao.delete(id); } @Override public User load(int id) { return userDao.load(id); } }
7, 测试
package com.yangw.spring.test; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yangw.spring.action.UserAction; import com.yangw.spring.model.User; public class TestSpring { //1,创建Spring工厂 BeanFactory factory= new ClassPathXmlApplicationContext("beans2.xml"); @Test public void testUser(){ //2,通过工厂获取Spring的对象 UserAction userAction = factory.getBean("userAction", UserAction.class); User u1=new User(1,"yangw"); userAction.setUser(u1); userAction.add(); userAction.delete(); userAction.load(); } }
8, Spring实现动态代理(基于annotation方式)
导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--1, 打开Spring的annotation --> <context:annotation-config/> <!-- 2, 设定Spring去那些包中找annotation --> <context:component-scan base-package="com.yangw.spring" /> <!-- 打开基于annotation的aop自动代理 --> <aop:aspectj-autoproxy /> </beans>
切面类
package com.yangw.spring.proxy; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Component("logAspect") //交给Spring管理 @Aspect //说明是一个切面类 public class LogAspect { //前置通知 // 第1个"*": 任意返回值 // 第2个"*": com.yangw.spring.dao包中的所有类 // 第3个"*": add*表示以add开头的所有方法 // "(..)" : 表示方法参数是任意值 // "||" : 可以用或表达式加入多个条件 /** * 函数调用之前执行 */ @Before("execution(* com.yangw.spring.dao.*.add*(..))||" +"execution(* com.yangw.spring.dao.*.delete*(..))||" +"execution(* com.yangw.spring.dao.*.update*(..))") public void logStart(JoinPoint jp){ System.out.println(jp.getTarget()); //得到执行的类 System.out.println(jp.getSignature().getName()); //得到执行的方法名 Logger.info("log start."); } /** * 函数调用之后执行 */ @After("execution(* com.yangw.spring.dao.*.add*(..))||" +"execution(* com.yangw.spring.dao.*.delete*(..))||" +"execution(* com.yangw.spring.dao.*.update*(..))") public void logEnd(JoinPoint jp){ System.out.println(jp.getTarget()); //得到执行的类 System.out.println(jp.getSignature().getName()); //得到执行的方法名 Logger.info("log end."); } /** * 函数调用过程中执行 */ @Around("execution(* com.yangw.spring.dao.*.add*(..))||" +"execution(* com.yangw.spring.dao.*.delete*(..))||" +"execution(* com.yangw.spring.dao.*.update*(..))") public void logAround(ProceedingJoinPoint pjp) throws Throwable{ Logger.info("log around start"); pjp.proceed(); //让程序往下执行 Logger.info("log around end."); } }
测试
package com.yangw.spring.test; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yangw.spring.action.UserAction; import com.yangw.spring.model.User; public class TestSpring { //1,创建Spring工厂 BeanFactory factory= new ClassPathXmlApplicationContext("beans3.xml"); @Test public void testUser(){ //2,通过工厂获取Spring的对象 UserAction userAction = factory.getBean("userAction", UserAction.class); User u1=new User(1,"yangw"); userAction.setUser(u1); userAction.add(); userAction.delete(); userAction.load(); } }
测试结果
Mon Oct 21 19:13:29 CST 2013----log around start com.yangw.spring.dao.UserDao@18ce14a add Mon Oct 21 19:13:29 CST 2013----log start. add :User [id=1, username=yangw] Mon Oct 21 19:13:29 CST 2013----log around end. com.yangw.spring.dao.UserDao@18ce14a add Mon Oct 21 19:13:29 CST 2013----log end. Mon Oct 21 19:13:29 CST 2013----log around start com.yangw.spring.dao.UserDao@18ce14a delete Mon Oct 21 19:13:29 CST 2013----log start. delete :0 Mon Oct 21 19:13:29 CST 2013----log around end. com.yangw.spring.dao.UserDao@18ce14a delete Mon Oct 21 19:13:29 CST 2013----log end. load :0 null
9, Spring实现动态代理(基于xml方式) 一般这种用的多
导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--1, 打开Spring的annotation --> <context:annotation-config/> <!-- 2, 设定Spring去那些包中找annotation --> <context:component-scan base-package="com.yangw.spring" /> <aop:config> <!-- 定义切面 --> <aop:aspect id="myLogAspect" ref="logAspect"> <!-- 在哪些位置加入相应的Aspect--> <aop:pointcut id="logPointCut" expression="execution(* com.yangw.spring.dao.*.add*(..))|| execution(* com.yangw.spring.dao.*.delete*(..))|| execution(* com.yangw.spring.dao.*.update*(..))" /> <!-- 定义通知 --> <aop:before method="logStart" pointcut-ref="logPointCut"/> <aop:after method="logEnd" pointcut-ref="logPointCut"/> <aop:around method="logAround" pointcut-ref="logPointCut"/> </aop:aspect> </aop:config> </beans>
package com.yangw.spring.proxy; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; @Component("logAspect") //交给Spring管理 public class LogAspect1 { public void logStart(JoinPoint jp){ System.out.println(jp.getTarget()); //得到执行的类 System.out.println(jp.getSignature().getName()); //得到执行的方法名 Logger.info("log start."); } public void logEnd(JoinPoint jp){ System.out.println(jp.getTarget()); //得到执行的类 System.out.println(jp.getSignature().getName()); //得到执行的方法名 Logger.info("log end."); } public void logAround(ProceedingJoinPoint pjp) throws Throwable{ Logger.info("log around start"); pjp.proceed(); //让程序往下执行 Logger.info("log around end."); } }
测试和结果与前面的基于annotation的一模一样,不在赘述!
Spring02-AOP的更多相关文章
- JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示
一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将 ...
- Spring第二天——IOC注解操作与AOP概念
大致内容 spring的bean管理(注解实现) AOP原理 log4j介绍 spring整合web项目的演示 一.spring注解实现bean管理 注解: 代码中一些特殊的标记,使用注解也可以完成一 ...
- spring-02
spring-02 1.谈谈你对 Spring 的理解 Spring 是一个开源框架,为简化企业级应用开发而生.Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.S ...
- Spring03——有关于 Spring AOP 的总结
本文将为各位带来 Spring 的另一个重点知识点 -- Spring AOP.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识点. 什么是 AOP 面向切面编程 ...
- 基于spring注解AOP的异常处理
一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- 学习AOP之透过Spring的Ioc理解Advisor
花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- .Net中的AOP系列之构建一个汽车租赁应用
返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...
随机推荐
- 【Centos7】安装nginx
1.安装必要的rpm yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel 2.安装PCRE : 作用 ...
- Linux 常用性能工具简介
一.wget 文件下载 使用wget下载单个文件:wget URL 下载并以不同的文件名保存:wget -O wordpress.zip URL wget限速下载:wget --limit-rate= ...
- HashMap 数组应用面试题(Point)
今天看了一题面试题,以为很简单,不过自己写了遍,没有完全写出来: 题目是这样的: 给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点.按照距离由小 ...
- 通俗语言解释内外网IP与端口映射
IP:分为外网IP和内网IP 也就是我们说的外网IP属于实体IP 实体IP,它是独一无二的,在网络的世界里,每一部计算机的都有他的位置,一个 IP 就好似一个门牌!例如,你要去百度的网站的话,就要去『 ...
- Python学习笔记开篇
已经快30岁了,中专学历,不会什么技术,因为好吃懒做最喜欢的就是吃肉睡觉. 每次想学习技术如PhotoShop,绘声绘影,PHP,易语言,按键精灵都只是3分钟热血. 今天我想在业余时间学习Python ...
- 网上搜索到的 比较好的mysql查询语句练习题
Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...
- JS判断当前使用设备是pc端还是web端(转MirageFireFox)
js判断当前设备 最近用bootstrap做自适应,发现仍然很难很好的兼容web端和PC端的现实. 仔细观察百度,淘宝,京东等大型网站,发现这些网站都有对应不同客户端的子站. 站点 PC端url we ...
- HTML5新增属性data-*和js/jquery之间的交互
HTML5新增属性data- data-自定义属性,这种方式的自定义属性解决属性混乱无状态管理的现状 书写实例 <div data-role="page" data-last ...
- 三分钟读懂TT猫分布式、微服务和集群之路
针对入门新手的普及,有过大型网站技术架构牛人路过,别耽误浪费了时间,阅读之前,请确保有一定的网络基础,熟练使用Linux,浏览大概需要3-5分钟的时间,结尾有彩蛋. 目录 分布式 微服务 负载均衡集群 ...
- webservice时间类型XMLGregorianCalendar和Date的转换
//ISO日期转换为UTC日期 public XMLGregorianCalendar xmlToDate(Date date){ GregorianCalendar cal = new Gregor ...