- 浏览: 91018 次
文章分类
最新评论
目标Target:就是通知织入的类主体。
连接点JoinPiont:每个方法都是一个连接点(方法调用前、方法调用后、方法异常、方法前后)
切点pointCut:并不是所用连接点都要织入通知,织入通知的连接点称为切点。
引介Introdution:特殊的通知,为目标类增加属性和方法。
通知Advice:通知是切点上织入的一段代码,(方法前通知、方法后通知、异常通知、前后环绕通知、引介)。
织入Weaving:将通知织入切点的过程;spring采用动态代理的方式,Aspectj采用编译期和类装载织入。
代理Proxy:代理类可能是与原类同接口的类,也可以是原类的子类。
下午好,第一个参数:nick
切点方法名:sayHello
目标类名:org.nick.test.Waiter@51a23566
欢迎光临:nick
基于beans.xml的前置通知 p73
关键:用一个接口接收代理对象,不然会报com.sun.proxy.$Proxy0 cannot be cast to org.nick.test.Person异常
如果用类来接收,就需要在proxy下设置:p:proxyTargetClass ="true" 这样就不用实现BasePerson接口了,同时将使用CGLIB的代理方法而不是sun的代理方法,这两种代理方法在创建对象和代理对象运行效率上存在差异,一般将singleton对象设置为CGLIB代理,加快其运行效率。
使用ProxyFactoryBean来创建代理对象实例,而java中使用的是ProxyFactory,实际上ProxyFactoryBean使用ProxyFactory方法创建的;
使用 p:interceptorNames 表示通知.类型可以是String[]型的,自动根据类型判定是前置或后置通知。p75
和p:interfaces这里可以是多个接口,用<list><value>标签
后置通知:实现AfterReturningAdvice接口
环绕通知:实现MethodInterceptor接口
唯一方法;invoke(MethodInvocation invocation)
Object[] args = invocation.getArguments();获取切点方法的参数,入参
Object obj = invocation.proceed();
retrun obj;
在invocation.proceed()前的code在切点方法前执行,在之后的code在切点方法之后执行。
异常通知:实现ThrowsAdvice接口
自定义方法:必须名为afterThrowing(Method method,Object[] args,Object obj,Exception ex){} 切点方法、切点方法参数、目标对象、异常
或afterThrowing(Exception ex){}
前面都是对一个对象的所有方法进行了织入,实际中只需要对指定的方法作为切点:切点切面--->PointcutAdvisor
**************切点:对连接点定位,有选择性的对目标方法进行织入****************
定位:
通过ClassFilter定位目标类 p79
通过MethodMatcher定位目标方法
切面:通知+切点
1、静态方法切点:字符串匹配方法切点 & 正则表达式匹配方法切点
1.1、字符串匹配方法切点 继承StaticMethodMatcherPointcutAdvisor
现只对Waiter的sayBye方法进行织入:
现要对 目标对象、通知、切面、代理对象 进行配置
欢迎光临:skx
下午好:skx
切点方法名:sayBye
目标类名:org.nick.test.Waiter@4dea0aa2
下次再来:skx
这里就只对sayBye进行了织入;
正则表达式匹对方法:使用字符串匹对类和方法,书写的code较多,使用正则表达只需要配置xml就可以完成定位
2、自动创建代理BeanPostProcessor
上面的每个对象都要创建一个代理对象,显得比较麻烦,这里将引入自动创建代理。
BeanNameAutoProxyCreator基于Bean配置的命名规则自动代理器,可以同时代理多个必须使用CGLIB代理
cglib自动创建代理:
DefaultAdvisorAutoProxyCreator 基于切面Advisor的自动创建代理器
下午好:skx
切点方法名:sayHello
目标类名:org.nick.test.Waiter@6467b8ff
欢迎光临:skx
下午好:nick
切点方法名:sayHello
目标类名:org.nick.test.Person@690a614
你好:nick
下次再来:skx
再见:nick
切面正确加载!只对*hello方法织入
连接点JoinPiont:每个方法都是一个连接点(方法调用前、方法调用后、方法异常、方法前后)
切点pointCut:并不是所用连接点都要织入通知,织入通知的连接点称为切点。
引介Introdution:特殊的通知,为目标类增加属性和方法。
通知Advice:通知是切点上织入的一段代码,(方法前通知、方法后通知、异常通知、前后环绕通知、引介)。
织入Weaving:将通知织入切点的过程;spring采用动态代理的方式,Aspectj采用编译期和类装载织入。
代理Proxy:代理类可能是与原类同接口的类,也可以是原类的子类。
package org.nick.test; import org.springframework.aop.framework.ProxyFactory; public class Test { public static void main(String[] str){ //为目标类Waiter织入通知 //创建目标对象 Waiter target = new Waiter(); //创建通知类实例 MyBeforeMethod advice = new MyBeforeMethod(); //创建代理对象,接管目标对象 //这是spring提供的代理工厂类 ProxyFactory proxy = new ProxyFactory(); //设置要代理的目标类 //proxy将接管target的所用操作 proxy.setTarget(target); //为代理对添加前置通知 proxy.addAdvice(advice); //将设置好通知的代理对象返回给目标对象 target = (Waiter) proxy.getProxy(); //执行原有的方法 //这里是每个方法都设置的通知 target.sayHello("nick"); } } package org.nick.test; public class Waiter { public void sayHello(String name){ System.out.print("欢迎光临:"+name); } public void sayBye(String name){ System.out.println("下次再来:"+name); } } package org.nick.test; import java.lang.reflect.Method; import org.apache.commons.httpclient.methods.GetMethod; import org.springframework.aop.MethodBeforeAdvice; public class MyBeforeMethod implements MethodBeforeAdvice { //methodname 目标类的方法名 //methodargs 切点方法的参数 //typename 目标类 @Override public void before(Method methodname, Object[] methodargs, Object typename) throws Throwable { //获取切点方法参数 System.out.println("下午好,第一个参数:"+methodargs[0]); //获取切点的方法名 System.out.println("切点方法名:"+methodname.getName()); //获取目标类 System.out.println("目标类名:"+typename.toString()); } }
下午好,第一个参数:nick
切点方法名:sayHello
目标类名:org.nick.test.Waiter@51a23566
欢迎光临:nick
基于beans.xml的前置通知 p73
关键:用一个接口接收代理对象,不然会报com.sun.proxy.$Proxy0 cannot be cast to org.nick.test.Person异常
如果用类来接收,就需要在proxy下设置:p:proxyTargetClass ="true" 这样就不用实现BasePerson接口了,同时将使用CGLIB的代理方法而不是sun的代理方法,这两种代理方法在创建对象和代理对象运行效率上存在差异,一般将singleton对象设置为CGLIB代理,加快其运行效率。
使用ProxyFactoryBean来创建代理对象实例,而java中使用的是ProxyFactory,实际上ProxyFactoryBean使用ProxyFactory方法创建的;
使用 p:interceptorNames 表示通知.类型可以是String[]型的,自动根据类型判定是前置或后置通知。p75
和p:interfaces这里可以是多个接口,用<list><value>标签
<?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:p="http://www.springframework.org/schema/p" 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.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> <bean id="target" class="org.nick.test.Person"></bean> <bean id="advice" class="org.nick.test.MyBeforeMethod"></bean> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean" p:interfaces="org.nick.test.BasePerson" p:target-ref="target" p:interceptorNames="advice" /> </beans> package org.nick.test; public interface BasePerson { public void sayHello(String name); public void sayBye(String name); } package org.nick.test; public class Person implements BasePerson { @Override public void sayHello(String name) { System.out.println("你好:"+name); } @Override public void sayBye(String name) { System.out.println("再见:"+name); } } package org.nick.test; import org.springframework.aop.framework.ProxyFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test2 { public static void main(String[] str){ //加载beans.xml文件 ApplicationContext ac = new ClassPathXmlApplicationContext("conf/beans.xml"); BasePerson skx =(BasePerson) ac.getBean("proxy"); skx.sayHello("skx"); } }
后置通知:实现AfterReturningAdvice接口
环绕通知:实现MethodInterceptor接口
唯一方法;invoke(MethodInvocation invocation)
Object[] args = invocation.getArguments();获取切点方法的参数,入参
Object obj = invocation.proceed();
retrun obj;
在invocation.proceed()前的code在切点方法前执行,在之后的code在切点方法之后执行。
异常通知:实现ThrowsAdvice接口
自定义方法:必须名为afterThrowing(Method method,Object[] args,Object obj,Exception ex){} 切点方法、切点方法参数、目标对象、异常
或afterThrowing(Exception ex){}
前面都是对一个对象的所有方法进行了织入,实际中只需要对指定的方法作为切点:切点切面--->PointcutAdvisor
**************切点:对连接点定位,有选择性的对目标方法进行织入****************
定位:
通过ClassFilter定位目标类 p79
通过MethodMatcher定位目标方法
切面:通知+切点
1、静态方法切点:字符串匹配方法切点 & 正则表达式匹配方法切点
1.1、字符串匹配方法切点 继承StaticMethodMatcherPointcutAdvisor
现只对Waiter的sayBye方法进行织入:
现要对 目标对象、通知、切面、代理对象 进行配置
<bean id="target" class="org.nick.test.Waiter"></bean> <bean id="advice" class="org.nick.test.MyBeforeMethod"></bean> <!-- 切面是需要通知code,除了通知code也可以陪着target和class/interfces信息的,一般在proxy那里配置--> <bean id="advisor" class="org.nick.test.StaticStringPointCut" p:advice-ref="advice" /> <!-- [color=green]引用切面,配置interceptorNames="切面"而不是通知了[/color] --> <!-- "P:proxyTargetClass" associated with an element type "bean" is not bound. --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="advisor" p:target-ref="target" p:proxyTargetClass="true"/> package org.nick.test; import java.lang.reflect.Method; import org.springframework.aop.ClassFilter; import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; public class StaticStringPointCut extends StaticMethodMatcherPointcutAdvisor { @Override public boolean matches(Method arg0, Class<?> arg1) { return "sayBye".equals(arg0.getName()); } //默认情况下,匹配所有类下的方法,这里增加一个ClassFilter只匹配Waiter下的方法 public ClassFilter getClassFilter(){ //复写其中的matches方法 return new ClassFilter(){ public boolean matches(Class clazz){ // Class1.isAssignableFrom(Class2) //是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口。 return Waiter.class.isAssignableFrom(clazz); } }; } } package org.nick.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test3 { public static void main(String[] args) { //加载beans.xml文件 ApplicationContext ac = new ClassPathXmlApplicationContext("conf/beans.xml"); Waiter skx =(Waiter) ac.getBean("proxy"); skx.sayHello("skx"); skx.sayBye("skx"); } }
欢迎光临:skx
下午好:skx
切点方法名:sayBye
目标类名:org.nick.test.Waiter@4dea0aa2
下次再来:skx
这里就只对sayBye进行了织入;
正则表达式匹对方法:使用字符串匹对类和方法,书写的code较多,使用正则表达只需要配置xml就可以完成定位
<!-- 正则匹配方法 --> <bean id="regexAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" p:advice-ref="advice"> <property name="patterns"> <list> <value>.*Hello.*</value> </list> </property> </bean> <!-- 引用切面,配置interceptorNames="切面"而不是通知了 --> <!-- "P:proxyTargetClass" associated with an element type "bean" is not bound. --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="regexAdvisor" p:target-ref="target" p:proxyTargetClass="true"/> <!-- 正则匹配方法 --> <bean id="regexAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" p:advice-ref="advice"> <property name="patterns"> <list> <value>.*Hello.*</value> </list> </property> </bean> <!-- 引用切面,配置interceptorNames="切面"而不是通知了 --> <!-- "P:proxyTargetClass" associated with an element type "bean" is not bound. --> <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="regexAdvisor" p:target-ref="target" p:proxyTargetClass="true"/>
2、自动创建代理BeanPostProcessor
上面的每个对象都要创建一个代理对象,显得比较麻烦,这里将引入自动创建代理。
BeanNameAutoProxyCreator基于Bean配置的命名规则自动代理器,可以同时代理多个必须使用CGLIB代理
<bean id="target" class="org.nick.test.Waiter"></bean> <bean id="advice" class="org.nick.test.MyBeforeMethod"></bean>
<!--可以匿名创建--> <bean id = "atuoProxy" class = "org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" p:beanNames="*target" p:interceptorNames = "advice" /> public static void main(String[] args) { //加载beans.xml文件 ApplicationContext ac = new ClassPathXmlApplicationContext("conf/beans.xml"); //注意这里是直接将target取出来,就已经是代理好了的对象了 Waiter skx =(Waiter) ac.getBean("target"); skx.sayHello("skx"); skx.sayBye("skx"); }
cglib自动创建代理:
<bean id="target" class="org.nick.test.Waiter"></bean> <bean id="ptarget" class="org.nick.test.Person"></bean> <bean id="advice" class="org.nick.test.MyBeforeMethod"></bean> <bean id = "atuoProxy" class = "org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" p:beanNames="*target" p:interceptorNames = "advice" p:optimize="true" /> public static void main(String[] args) { //加载beans.xml文件 ApplicationContext ac = new ClassPathXmlApplicationContext("conf/beans.xml"); //注意这里是直接将target取出来,就已经是代理好了的对象了 Waiter skx =(Waiter) ac.getBean("target"); Person nick =(Person) ac.getBean("ptarget"); skx.sayHello("skx"); nick.sayBye("nick"); }
DefaultAdvisorAutoProxyCreator 基于切面Advisor的自动创建代理器
<bean id="target" class="org.nick.test.Waiter"></bean> <bean id="ptarget" class="org.nick.test.Person"></bean> <bean id="advice" class="org.nick.test.MyBeforeMethod"></bean> <bean id="regexAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" p:advice-ref="advice" p:patterns=".*Hello.*" /> <!-- 自动加载切面对象 --> <bean id = "atuoProxy" class = "org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" p:optimize="true" /> public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("conf/beans.xml"); Waiter skx =(Waiter) ac.getBean("target"); Person nick =(Person) ac.getBean("ptarget"); skx.sayHello("skx"); nick.sayHello("nick"); skx.sayBye("skx"); nick.sayBye("nick"); }
下午好:skx
切点方法名:sayHello
目标类名:org.nick.test.Waiter@6467b8ff
欢迎光临:skx
下午好:nick
切点方法名:sayHello
目标类名:org.nick.test.Person@690a614
你好:nick
下次再来:skx
再见:nick
切面正确加载!只对*hello方法织入
发表评论
-
41、解决HttpServletResponse输出的中文乱码问题
2015-04-12 21:48 1215response返回有两种,一种是字节流outputs ... -
41、轮询
2015-04-12 08:50 0浏览器关闭使session失效 ... -
40、spring ajax/easyui 中文乱码的解决
2015-04-04 14:52 692使用spingmvc,在JS里面通过ajax发送请求,并 ... -
39、.net
2015-03-28 23:12 542熟悉java编程,自然学习c#就会比较容易,有几个点需要说明下 ... -
38、servlet-- JSTL+EL(c标签、${})
2015-03-23 15:57 780参看:http://www.cnblogs.com/xdp-g ... -
37、servlet--jsp
2015-03-23 15:07 493不管是JSP还是Servlet,虽然都可以用于开发动 ... -
36、servlet--防止表单重复提交
2015-03-23 14:33 7101、在网络延迟会或服务器反应过慢的情况下让用户有时间点击多次s ... -
35、servlet--servletContext
2015-03-22 13:41 474servletContext接口是Servlet中最大的一个接 ... -
34、servlet--会话技术/购物车demo/y验证码
2015-03-21 23:40 586会话Session and Cookie 1、session: ... -
33、servlet--转发/web开发指导思想
2015-03-21 12:31 445转发: req.getRequestDispatcher(&q ... -
32、servlet --重定向/下载/缓存/中文乱码
2015-03-20 23:21 1055重定向1、sendRedirect rep.sendRedir ... -
31、servlet--开发方式
2015-03-20 21:55 633servlet:利用java技术开发动态网页的技术,是学习ja ... -
30、servlet---tomcat原理
2015-03-20 18:20 675Servlet出现得早,servlet很强大,但是se ... -
29、servlet--jsp执行过程
2015-03-20 15:08 446J2EE的13种核心技术:JDBC、JNDI、EJBs、 ... -
29、springmvc+spring+mybatis+oracle12的demo
2015-03-15 20:29 0每次搭建都要重头搭建,累~~ 注意:用12c的jdbc 在安 ... -
27、Tomcat多次加载项目问题
2015-03-12 15:30 561错误配置方式: <Host name="lo ... -
26、数据分页(jsp+servlet)
2015-03-12 15:19 472随着数据库中存储的数据的增多,满足用户查询条件的数据也 ... -
llll.文档设计
2015-03-11 13:31 0设计文档与代码实现到 ... -
24、webservice_短信接口
2015-03-11 10:48 801http://blog.csdn.net/sxdtzhaoxi ... -
25、RMI_demo1
2015-03-11 10:48 426Java RMI 指的是远程方法调用 (Remote Meth ...
相关推荐
Spring AOP provides an Alliance-compliant aspect-oriented programming implementation allowing you to define method interceptors and pointcuts to cleanly decouple code that implements functionality ...
在Java开发中,AOP(Aspect Oriented Programming)是一种编程范式,它将系统中的关注点(如日志、安全检查、性能统计等)分离出来,形成独立的“切面”,然后将这些切面织入到主业务逻辑中。Spring AOP通过代理模式...
Spring AOP,全称Aspect Oriented Programming(面向切面编程),是Spring框架的核心部分之一,它为Java开发者提供了强大的面向切面的编程能力。本文将围绕spring-aop.jar这个核心组件,详细探讨Spring AOP的原理、...
Spring AOP,即Aspect Oriented Programming(面向切面编程),是Spring框架中的一个关键模块,它的主要目标是简化代码的维护和提高程序的可复用性。通过AOP,我们可以将关注点分离,把那些横切多个对象的通用行为...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它为开发者提供了声明式事务管理、日志记录、权限控制等核心功能。在4.0.0.RELEASE版本中,Spring AOP进一步优化了其性能和...
Spring AOP,全称为Aspect-Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它为Java应用程序提供了强大的横切关注点管理能力。在传统的面向对象编程中,我们往往需要在多个类或方法中重复编写...
Spring AOP,全称Aspect-Oriented Programming(面向切面编程),是Spring框架的一个重要组成部分。它是对传统面向对象编程(OOP)的一种补充,主要处理系统级服务,如日志、事务管理、性能监控等,将这些横切关注点...
在Java EE(现称为Jakarta EE)开发中,AOP(Aspect-Oriented Programming,面向切面编程)是一个重要的概念,它允许程序员定义“切面”,这些切面封装了跨越多个对象的行为或责任。本话题将围绕标题和描述中提到的...
Spring AOP,全称Aspect-Oriented Programming,是Spring框架中的一个重要组成部分,它引入了面向切面编程的概念,使得开发者可以方便地实现横切关注点,如日志、事务管理等,而无需侵入到业务代码中。在这个例子中...
在软件开发中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种重要的设计模式,它允许开发者将关注点分离,使得业务逻辑与系统横切关注点(如日志、事务管理等)解耦。Spring框架中的AOP模块为开发者...
在Java开发领域,Spring框架是不可或缺的一部分,而Spring AOP(Aspect Oriented Programming,面向切面编程)则是Spring框架中的重要模块,它扩展了传统的面向对象编程,允许开发者定义“切面”,这些切面可以封装...
Spring AOP,即Aspect-Oriented Programming(面向切面编程),是Spring框架的重要组成部分,它为应用程序提供了一种模块化和声明式的方式来处理横切关注点,如日志、事务管理、性能监控等。在本"Spring-AOP源码Demo...
此外,它还支持消息源、事件传播、国际化和AOP(Aspect Oriented Programming,面向切面编程)的应用。 3. **spring-beans-4.0.0.RELEASE.jar**:负责处理bean的定义、实例化、配置和管理。这个模块实现了bean的...
- AOP是Aspect Oriented Programming的缩写,通过运行时动态代理实现程序功能的统一维护。 - 在Spring框架中,AOP用于隔离交叉业务逻辑,如事务管理、日志、安全检查和缓存,使其独立于主业务逻辑。 - AOP能够...
标题中的“spring-aop”指的是Spring框架中的面向切面编程(Aspect-Oriented Programming, AOP)模块,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的核心概念包括切面(Aspect)、通知...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对现有代码进行功能增强的技术。本文将深入探讨Spring AOP的源码,帮助开发者理解其...
本资源"java开发常用jar包之spring--aop.rar"聚焦于Spring框架的一个重要组件——Aspect Oriented Programming(面向切面编程,简称AOP)。AOP是Spring框架的核心特性之一,它允许开发者将关注点从核心业务逻辑中...