Spring4第四讲学习笔记,AOP面向切面编程
2017-06-07 23:04
786 查看
bean的作用域,scope 默认是singleton单例,整个容器中只有一个对象实例
prototype原型,每次获取bean对象都产生一个新对象
注意:在整合struts2和spring时,需要将action设置为scope="prototype"
1.静态代理的角色分析,
抽象角色:一般使用接口或者抽象类实现.interface Rent
真实角色:被代理的角色 Host 需要实现Rent接口
代理角色:代理真实角色,代理真实角色后一般会作一些附属操作 需要实现Rent接口
客户: 使用代理角色来进行一些操作 客户找代理
使用静态代理的好处
1.使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
2.公共的业务由代理来完成,实现业务的分工
3.公共业务发生扩展的时候,会变得更加集中和方便
缺点:代理类多了,工作量就会变大,开发效率就会降低。
2.动态代理
1.动态代理和静态代理的角色是一样的
2.动态代理的代理类是动态生成的
3.分为两类 一类基于接口的动态代理,如jdk动态代理
,一类是基于类的动态代理,如cglib (读法:C G lib)
现在使用javaisit动态生成
4.jdk动态代理---java反射包中的proxy类InvocationHandler接口,它只能代理接口。
一个动态代理一般代理某一类业务。一个动态代理可以代理多个类。
3.面向切面编程aop aspect oriented programing
2.aop在Spring中的运用
提供声明事务的服务
允许用户自定义切面
传统的编程模式是JSP--Action----Service---Dao 自上而下,纵向编程
3.aop在不改变原有的代码的情况下,增加新的功能
aop编程模式:横向的编程 log()方法插入Service中
aop的好处:a.使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
b.公共的业务由代理类来完成---实现业务的分工
c.公共业务发生扩展时将会变得更加集中和方便
4.名词解释
关注点:增加的某个业务,如日志,安全,缓存,事务等
切面aspect:一个关注点的模块化。就是把关注点封装成一个类。一个横向的切面可能会横切多个业务类。
连接点:表示关注点的执行。
通知advice:在某个业务执行的前后公共业务执行。通知类型分为,前置通知,后置通知,异常通知,最终通知等。
织入weaving:把切面连接到其他对象上。
5.Spring就是封装动态代理,提高开发效率
Spring将公共的业务方法,和业务类关联起来, 执行业务类的时候, Spring也去执行公共的业务方法
spring aop就是将公共的业务如日志安全等和领域业务结合,当执行领域业务时将会把公共的业务加进来,实现公共业务的重复利用。
它使得领域业务更纯粹,程序员专注于领域业务。其本质还是动态代理。
具体代码实现:
静态代理代码:就是写一个代理类,里面有一个真实角色的引用,通过代理类的构造器接受这个真实角色,代理类执行真实角色的方法,并附加一些代理类的附属方法。
动态代理代码:
3.使用Spring实现aop,面向切面的编程。
导入相关jar包,多了两个古来的jar包。
aopalliance.jar
aspectjweaver.jar
commons-logging-1.1.1.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-context-support-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-orm-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar
配置文件beans.xml
以前的头文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
在以前的头文件下增加
公共业务方法 在 业务类的 执行前和执行后 执行。
业务类
第二种方法,使用注解实现AOP编程
公共业务方法单独封装成类,这个类打上@Apspect切面标记
在公共业务方法前面添加@Before 或者@After等 表示在 核心业务执行前或执行后 执行
配置文件
prototype原型,每次获取bean对象都产生一个新对象
注意:在整合struts2和spring时,需要将action设置为scope="prototype"
1.静态代理的角色分析,
抽象角色:一般使用接口或者抽象类实现.interface Rent
真实角色:被代理的角色 Host 需要实现Rent接口
代理角色:代理真实角色,代理真实角色后一般会作一些附属操作 需要实现Rent接口
客户: 使用代理角色来进行一些操作 客户找代理
使用静态代理的好处
1.使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
2.公共的业务由代理来完成,实现业务的分工
3.公共业务发生扩展的时候,会变得更加集中和方便
缺点:代理类多了,工作量就会变大,开发效率就会降低。
2.动态代理
1.动态代理和静态代理的角色是一样的
2.动态代理的代理类是动态生成的
3.分为两类 一类基于接口的动态代理,如jdk动态代理
,一类是基于类的动态代理,如cglib (读法:C G lib)
现在使用javaisit动态生成
4.jdk动态代理---java反射包中的proxy类InvocationHandler接口,它只能代理接口。
一个动态代理一般代理某一类业务。一个动态代理可以代理多个类。
3.面向切面编程aop aspect oriented programing
2.aop在Spring中的运用
提供声明事务的服务
允许用户自定义切面
传统的编程模式是JSP--Action----Service---Dao 自上而下,纵向编程
3.aop在不改变原有的代码的情况下,增加新的功能
aop编程模式:横向的编程 log()方法插入Service中
aop的好处:a.使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情
b.公共的业务由代理类来完成---实现业务的分工
c.公共业务发生扩展时将会变得更加集中和方便
4.名词解释
关注点:增加的某个业务,如日志,安全,缓存,事务等
切面aspect:一个关注点的模块化。就是把关注点封装成一个类。一个横向的切面可能会横切多个业务类。
连接点:表示关注点的执行。
通知advice:在某个业务执行的前后公共业务执行。通知类型分为,前置通知,后置通知,异常通知,最终通知等。
织入weaving:把切面连接到其他对象上。
5.Spring就是封装动态代理,提高开发效率
Spring将公共的业务方法,和业务类关联起来, 执行业务类的时候, Spring也去执行公共的业务方法
spring aop就是将公共的业务如日志安全等和领域业务结合,当执行领域业务时将会把公共的业务加进来,实现公共业务的重复利用。
它使得领域业务更纯粹,程序员专注于领域业务。其本质还是动态代理。
具体代码实现:
静态代理代码:就是写一个代理类,里面有一个真实角色的引用,通过代理类的构造器接受这个真实角色,代理类执行真实角色的方法,并附加一些代理类的附属方法。
动态代理代码:
package cn.sxt.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //import cn.sxt.service.UserService; public class ProxyInovationHandler implements InvocationHandler{ private Object target;// 目标对象--真实对象 public ProxyInovationHandler(Object target) { //通过构造方法接受真实对象 super(); this.target = target; } /** * 生成代理类 * */ public Object getProxy() { Object wrap = Proxy.newProxyInstacne(this.getClass().getClassLoader(),this.target.getClass().getInterfaces(),this); return wrap ; //共有三个参数,第一个是类加载器, 第二个是this.getClass().getClassLoader()或者new Class[]{this.target.getClass()}; 注意:由于proxy动态代理是基于接口的动态代理,所以要求目标对象必须是一个接口 第三个是调用处理器接口对象。 } public void log(String methodName) { // 用于记录日志 System.out.println("执行" + methodName + "方法"); } /** * proxy是代理类 method 代理类准备执行的方法 * */ @Override public Objectinvoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName());//公共事务,用于记录日志。 return method.invoke(this.target, args); } } |
导入相关jar包,多了两个古来的jar包。
aopalliance.jar
aspectjweaver.jar
commons-logging-1.1.1.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-context-support-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-orm-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar
配置文件beans.xml
以前的头文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
在以前的头文件下增加
beans.xml <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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <bean id="log" class="log.Log"/> <bean id="service" class="service.imp.serviceImp"/> <bean id="afterLog" class="log.AfterLog"/> <aop:config> <!--切入点准备切入的具体业务的具体位置 expression表达式 execution()固定 *所有返回值 --> <aop:pointcutexpression="execution(* service.imp.serviceImp.delete(..))" id="pointcut"/> //第一个* 表示全部返回值 ..表示任意参数 <!-- 把切入点和公共业务连接起来,配置通知 --> <aop:advisoradvice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans> |
package log; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; //业务执行前的公共事情,advice:通知 public class Log implements MethodBeforeAdvice{ 参数:method被调用的方法,参数列表,哪个对象执行method方法 @Override public void before(Method method, Object[] args, Object target) throws Throwable { String methodName=method.getName(); String className= target.getClass().getName(); System.out.println("类名为:"+className+"的"+methodName+"方法被执行"); } } package log; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class AfterLog implements AfterReturningAdvice{ /** * 目标方法执行后执行的通知 * returnValue--返回值 * method 被调用的方法对象 * args 被调用的方法对象的参数 * target 被调用的方法对象的目标对象 * */ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { String className = target.getClass().getName(); String methodName= method.getName(); System.out.println("类名是:"+className+"的"+methodName+"方法执行"); System.out.println("返回结果是"+returnValue); } } |
package service.imp; import servicee.service; public class serviceImp implements service { @Override public void add() { System.out.println("用户增加"); } @Override public void delete() { System.out.println("用户删除"); } @Override public void update() { System.out.println("用户更新"); } @Override public void search() { System.out.println("用户查询"); } } |
测试代码 package test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import servicee.service; public class test { public static void main(String[] args) { BeanFactory bf = new ClassPathXmlApplicationContext("beans.xml"); service svc = (service)bf.getBean("service"); svc.delete();//此业务方法一执行,公共事务在此方法前 和 后 都有执行 } } |
公共业务方法单独封装成类,这个类打上@Apspect切面标记
在公共业务方法前面添加@Before 或者@After等 表示在 核心业务执行前或执行后 执行
package log; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class Logg { @Before("execution(* service.imp.serviceImp.*(..))") 注意还有个表示所有返回值的 * 号 public void before(){ System.out.println("方法执行前执行"); } @After("execution(* service.imp.serviceImp.*(..))") public void after(){ System.out.println("方法执行后执行"); } } |
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <bean id="log" class="log.Log"/> <bean id="service" class="service.imp.serviceImp"/> <bean id="afterLog" class="log.AfterLog"/> <bean id="newLog" class="log.Logg"/> <!-- <aop:config> 切入点准备切入的具体业务的具体位置 expression表达式 execution()固定 *所有返回值 <aop:pointcut expression="execution(* service.imp.serviceImp.delete(..))" id="pointcut"/> 把切入点和公共业务连接起来,配置通知 <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> --> <aop:aspectj-autoproxy/> 注意书写 切面j-自动代理 </beans> |
相关文章推荐
- Spring学习笔记(AOP面向切面编程)
- Spring学习笔记 —— AOP(面向切面编程) 之使用ProxyFactoryBean实现AOP
- Spring学习笔记:面向切面(AOP)的基本定义
- spring学习笔记7--使用spring进行面向切面的(AOP)编程(1)注解方式实现
- 【spring源码学习】spring的AOP面向切面编程的实现解析
- Spring.Net学习 控制反转(IoC)和面向切面编程(AOP)
- Spring基础学习(八)——AOP面向切面编程
- Spring 学习(二) spring 面向切面编程(AOP)
- Spring学习之旅(二) AOP(面向切面编程)的使用
- Spring学习之AOP(面向切面编程)
- Spring学习(8)--AOP(面向切面编程)基础
- spring学习总结二-----面向切面编程(AOP)思想
- Spring学习三(AOP面向切面编程)
- Spring学习之深入AOP面向切面编程
- [Spring]面向切面编程AOP【学习笔记】
- Spring学习笔记(三)--面向切面编程AoP
- Spring.Net学习 控制反转(IoC)和面向切面编程(AOP) (转)
- Spring学习笔记3--面向切面(AOP)的例子
- Spring学习(六)-面向切面编程(AOP)
- Spring AOP学习笔记