重新学习之spring第二个程序,配置AOP面向切面编程

第一步:在配置好的ioc容器的基础上,导入面向切面编程所需要的jar包

(本案例用的是spring3.2.4,由于spring3.2.4的官网jar包中不再有依赖包,所以依赖包都是从网上找的)

第二步:配置applicationContext.xml(包括ioc对象配置,以及面向切面编程的相关配置)

 

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4         xmlns:aop="http://www.springframework.org/schema/aop"
 5         xmlns:tx="http://www.springframework.org/schema/tx"
 6         xsi:schemaLocation="
 7             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 8             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
 9             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
10
11     <!--
12         lazy-init:true 懒加载,初始ioc化容器的时候,不建立对象
13         lazy-init:false(默认) 不懒加载,初始化ioc容器的时候,就讲applicationContext.XML中所有配置的类的对象创建,并建立关系
14         scope:prototype每次取对应id的类的对象,都新创建一个
15         scope:singleton(默认)类似于单例模式,只要容器初始化一个类对象,以后所有的取用,都是取这一个
16       -->
17
18       <!-- 通过setter方法,依赖注入对象。控制反转 -->
19     <bean id="userDao" class="com.bjsxt.shang.dao.UserDao" lazy-init="default" scope="singleton"></bean>
20     <bean id="MyAction" class="com.bjsxt.shang.action.MyAction" lazy-init="default" scope="prototype">
21         <property name="userDao" ref="userDao"></property>
22     </bean>
23
24
25     <!-- 定义一个切面(连接点,切入点,通知) -->
26     <bean id="log" class="com.bjsxt.shang.aop.LogTextAop"></bean>
27     <aop:config >
28         <!-- 切入点,将dao包下所有有参数或无参数传入的,有返回值或无返回值类型的公共方法,进行代理。 -->
29         <aop:pointcut expression="execution(public * com.bjsxt.shang.dao.*.*(..))" id="logCut"/>
30         <aop:pointcut expression="execution(public String com.bjsxt.shang.dao.*.*(..))" id="logCut2"/>
31         <aop:pointcut expression="execution(public * com.bjsxt.shang.dao.*.find*(..))" id="logCut3"/>
32         <!-- 通知,也就是代理对象中增强功能代码的编写 -->
33         <aop:aspect ref="log">
34             <!-- 代理,是为了抽出一些通用需求的功能,因此该属性指定的代理时调用增强功能的方法 -->
35             <!-- 连接点执行前或后,执行通用的代码 -->
36             <aop:before method="beforeRun1" pointcut-ref="logCut"/>
37             <aop:after method="afterRun2" pointcut-ref="logCut2"/>
38             <!-- 环绕通知,有参数的传递,可对参数传递进行处理 -->
39             <aop:around method="aroundRun" pointcut-ref="logCut3"/>
40         </aop:aspect>
41     </aop:config>
42
43
44
45 </beans>

View Code

 

第三步:在appliactionContext.xml中指定的面向切面编程的代理切面类。

 

 1 package com.bjsxt.shang.aop;
 2
 3 import java.util.Date;
 4
 5 import org.aspectj.lang.ProceedingJoinPoint;
 6
 7 import com.alibaba.fastjson.JSONObject;
 8 /**
 9  * 面向切面编程,是对一个集合的方法(切入点切中的符合表达式的所有方法)进行代理,也就是说在执行这些集合中的方法时,会执行该代理切面类中的相关指定方法,做到日志记录,增强功能,等等效果。
10  * 而且属于热插拔式的。像usb一样,可去掉,可插入。而不影响项目的主要功能
11 * @ClassName: LogTextAop
12 * @Description: TODO(这里用一句话描述这个类的作用)
13 * @author 尚晓飞
14 * @date 2014-8-29 下午2:55:38
15 *
16  */
17 public class LogTextAop {
18     /**
19      * 连接点(方法)执行前执行该方法
20     * @Title: beforeRun1
21     * @Description: TODO(这里用一句话描述这个方法的作用)
22     * @return void    返回类型
23     * @author 尚晓飞
24     * @date 2014-8-29 上午11:08:41
25      */
26     public void beforeRun1(){
27         System.out.println("LogTextAop.beforeRun1()连接点执行前,我执行了该方法。aop-----前---------");
28     }
29     /**
30      * 连接点(方法)执行后执行该方法
31     * @Title: afterRun2
32     * @Description: TODO(这里用一句话描述这个方法的作用)
33     * @return void    返回类型
34     * @author 尚晓飞
35     * @date 2014-8-29 下午1:47:40
36      */
37     public void afterRun2(){
38         System.out.println("LogTextAop.afterRun2()连接点执行后,我执行了该方法、aop-----后--------");
39     }
40
41     /**
42      * 连接点(方法)执行前后都会执行的方法
43     * @Title: aroundRun
44     * @Description: TODO(这里用一句话描述这个方法的作用)
45     * @param pjp
46     * @return
47     * @return Object    返回类型
48     * @author 尚晓飞
49     * @date 2014-8-29 下午2:05:39
50      */
51     public Object aroundRun(ProceedingJoinPoint pjp){
52         //获取委托类方法传入的参数
53         Object[] objs=pjp.getArgs();
54         //获取委托类方法的名字
55         String methdoName=pjp.getSignature().getName();
56         //获取委托类的一个对象
57         Object object=pjp.getTarget();
58
59         //生成一个jsonobject对象
60         JSONObject jsonObject=new JSONObject();
61
62         try {
63                 if(!methdoName.startsWith("find")){
64                     System.out.println("LogTextAop.aroundRun(连接点执行前执行----aop-around---前)");
65                         Object obj=pjp.proceed();
66                     System.out.println("LogTextAop.aroundRun(连接点执行后执行----aop-around---后)");
67                     return obj;
68
69                 }else{
70                     System.out.println("LogTextAop.aroundRun(连接点执行前执行----aoparound---前)");
71                     System.out.println("LogTextAop.aroundRun(操作时间)"+new Date().toLocaleString());
72                     System.out.println("LogTextAop.aroundRun(操作类型)"+methdoName);
73                     System.out.println("LogTextAop.aroundRun(操作内容)"+jsonObject.toJSONString(objs));
74                     Object obj=pjp.proceed();
75                     System.out.println("LogTextAop.aroundRun(连接点执行后----aoparound----后)");
76                     return obj;
77                 }
78         } catch (Throwable e) {
79             e.printStackTrace();
80         }
81         return null;
82     }
83
84 }

View Code

 

第四步:测试面向切面编程的demo(省去了action,dao包下的类的源代码)

 

 1 package com.bjsxt.shang.test;
 2
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5
 6 import com.bjsxt.shang.action.MyAction;
 7 import com.bjsxt.shang.dao.UserDao;
 8
 9 public class Test {
10     public static void main(String[] args) {
11
12
13
14                 //官方推荐,建立xml文件,配置程序中对象,和建立对象间关系的是applicationContext.xml
15                 //平民版的xml是 beans.xml controller.xml dao.xml service.xml
16                 //获取解析,并依赖注入applicationContext.XML文件的ioc容器
17                 //ApplicationContext acIoc=new ClassPathXmlApplicationContext("applicationContext.xml");
18                 ApplicationContext ioc=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
19
20
21                 //获取所有的ioc容器
22                 //BeanFactory是所有Spring Ioc容器的父接口
23                 //BeanFactory beanFactory=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
24
25                 UserDao dao=(UserDao)ioc.getBean("userDao");
26                 UserDao dao1=(UserDao) ioc.getBean("userDao");
27                 //测试IOC容器中生成的对象是不是单例的。
28                 System.out.println(dao==dao1);
29
30                 MyAction userAction=(MyAction) ioc.getBean("MyAction");
31                 //userAction.add();
32                 //userAction.lang();
33                 userAction.ds();
34     }
35
36 }

View Code

 

测试截图

 

 

 

 

AOP介绍
   Aspect Oriented Programing 面向切面编程
    (1)如果说面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系的话;
    (2)面向方面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即 可。
  AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。
     (1)前面我们讲的struts2中的拦截器,就是AOP的一种实现!

AOP的内部实现都是通过动态代理来实现。动态代理有两种常见的方式:
  1.    JDK提供的代理生成方式(Proxy,  InvocationHandle)
  2.    cglib 类库(spring和hibernate使用它)

AOP基本概念
}    连接点(Joinpoint)
◦     在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。 在Spring AOP中,一个连接点 总是 代表一个方法的执行。
}    切入点(Pointcut)
◦    匹配连接点(Joinpoint)的断言(是一种连接点的条件,判断特征)。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。
    -->public void com.bjsxt.dao.userDao.*.*()
              :所有userDao包下的无返回值,无参数传入的,公共方法
    -->public *()
              :所有的公共方法
    -->public void com.bjsxt.dao.userDao.*.(..)
              :所有userDao包下的有参传入的无返回值的,公共的方法。
}    通知(Advice)
◦    在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。
增强功能的代码编写区 。如日志记录,访问控制,增强功能。
}    切面(Aspect)
◦    一个关注点的模块化,这个关注点可能会横切多个对象。
包含了:连接点、切入点、通知。可以通过@Aspect定义为一个类
}    目标对象(Target Object)
     说白话就是----》委托类
◦    被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做被通知(advised) 对象。
}    织入(Weaving)
        制作代理类,和代理对象的过程
◦    把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象。

通知的类型
}    前置通知(Before advice)
◦    在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
}    返回后通知(After returning advice)
◦    在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
}    抛出异常后通知(After throwing advice)
◦    在方法抛出异常退出时执行的通知。
}    后通知(After (finally)advice)
◦    当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
}    环绕通知(Around Advice)
◦    包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。

 

时间: 2024-11-09 04:40:29

重新学习之spring第二个程序,配置AOP面向切面编程的相关文章

spring aop面向切面编程:如何来做一个强大的日志记录功能

这个东西怎么做:spring aop 面向切面编程 如何来做一个强大的日志记录功能模板; 昨天经理把这个任务交给我,让我为公司现在的项目加上一个详细的日志记录功能模板,对所有的操作,至少是增删改运作进行一个记录,其要记录操作者,以及执行的方法,IP,以及操作的方法的参数. 我以前做过类似的功能,不过是在filter里做的,通过filter来检查action请求,记录请求中的参数及action名字.但是今天公司这个是要求用spring aop来做,这样就可以在spring里对要进行的日志记录方法进

Spring之注解实现aop(面向切面编程)

1:Aop(aspect object programming)面向切面编程,名词解释:    1.1:功能:让关注点代码与业务逻辑代码分离    1.2:关注点        重复代码就叫做关注点    1.3:切面        关注点形成的类,就叫做切面(类)        面向切面编程,就是指对很多功能都有的重复代码抽取,再在运行的时候往业务方法上动态植入"切面类代码":    1.4:切入点        执行目标对象方法,动态植入切面代码        可以通过切入点表达式

【spring源码学习】spring的AOP面向切面编程的实现解析

一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口  =>org.springframework.aop.BeforeAdvice   org.springframework.aop.MethodBeforeAdvice  =>org.springframework.aop.AfterAdvice   org.springframework.aop.After

Spring实战4—面向切面编程

主要内容 面向切面编程的基本知识 为POJO创建切面 使用@AspectJ注解 为AspectJ的aspects注入依赖关系 在南方没有暖气的冬天,太冷了,非常想念北方有暖气的冬天.为了取暖,很多朋友通过空调取暖,但是空调需要耗电,也就需要交不少电费.没家都会有一个电表,每隔一段时间都会有记录员来家里收取这段时间的电费. 现在做个假设:去掉电表和电费收取员,因此也没有人定期来家里收电费.这时就需要我们隔段时间主动去电力公司交电费,尽管会有执着的家庭主妇会认真得记录每个月各个电器用了多少度电,并计

Spring中反向控制和面向切面编程的应用

引言 在J2EE的整个发展历程中,现在正是一个非常时刻.从很多方面来说,J2EE都是一个伟大的成功:它成功地在从前没有标准的地方建立了标准:大大提升了企业级软件的开放程度,并且得到了整个行业和开发者的广泛认可.然而,J2EE在一些方面已经开始捉襟见肘.J2EE应用开发的成本通常很高.J2EE应用项目至少和从前的非J2EE项目一样容易失败--如果不是更容易失败的话.这样的失败率高得让人难以接受.在这样的失败率之下,软件开发几乎变成了碰运气.而在J2EE遭遇失败的场景中,EJB通常都扮演着重要的角色

Spring AOP是怎么面向切面编程的

问题描述 SpringAOP面型切面编程是一个怎么样的实现机制,为什么要面向切面编程 解决方案 解决方案二:有:事前事中事后比如事前A网站每个页面都要用户验证,我把用户验证用AOP写,页面里就不写了.能达到也正用户是否合法.解决方案三:现象切面编程,意思就是在不改变源代码的情况下增加代码,那怎么做呢,就是用代理,在代理类里调用被代理类的方法,大概是这个样子!解决方案四:掌握AOP之前,需要先了解一下动态代理.动态代理一般分为两种,一种是在运行期织入,另一种是在编译期织入.运行期织入的实现有JDK

AOP面向切编程及在Spring中的使用方法

AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统的 OOP(Object-Oriented Programming, 面向对象编程)的补充 AOP 的主要编程对象是切面(aspect) 在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类 AOP 的好处: 每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级 业务模块更简洁, 只包含核心业务代

重新学习之spring第一个程序,配置IOC容器

第一步:导入相关jar包(此范例导入的是spring3.2.4版本,spring2.5版本只需要导入spring核心包即可)     第二步:在项目的src下配置applicationContext.xml的配置文件 applicationContext.xml文件   1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.o

使用Spring进行面向切面编程(AOP)---讲解+代码

6.1. 简介 6.2.4.1. 前置通知(Before advice) 一个切面里使用 @Before 注解声明前置通知: import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class BeforeExample {          @Before("com.xyz.myapp.SystemArchitecture.dataAccessOpe