Spring入门4.AOP配置深入
Spring入门4.AOP配置深入
代码下载 链接: http://pan.baidu.com/s/11mYEO 密码: x7wa
前言:
之前学习AOP中的一些概念,包括连接点、切入点(pointcut),切面(Aspect),Advice,Proxy代理等等,同时学历了使用XML配置AOP的方式,这一个过程中遇到很多的错误,比如配置文件中的<aop:aspect-autoproxy/>,如果在配置中没有添加这一行配置,就会编译出错。还有学习Advice的5种方式以及配置原理。
这一次我们深入的学习XML配置的内容,然后是Annotation的配置方式。
一、XML配置方式深入
1.配置切入点
配置切入点的时候需要给出属性pointcut的属性值,指定切入点表达式。同时还可以使用<aop:pointcut/>元素在<aop:config>中单独的定义切入点,实际上就是为切入点起一个名字,在后面多个Advice中使用。
<aop:config proxy-target-class=”true”>
<aop:pointcut id = “mypointcut1” expression=”execution(* com.yang.service.*(..))”/>
<aop:aspect id=”adviceAspect” ref=”aspectBean”>
<aop:before methos=”methodName” pointcut-ref=”mypointcut1”/>
</aop:aspect>
</aop:config>
这样就可以重复使用了,对于精简代码十分有帮助。
2.切入点指示符
SpringAOP提供了多种切入点指示符来定义切入点的规则。切入点知识符用于标明一个连接点在什么条件下关联到切入点。切入点表达式就是通过切入点指示符进行定义的,如execution就是一种切入点指示符。
在Spring3中的切入点指示符有:
execution:用于匹配执行方法的连接点,他是SpringAOP中最主要的切入点指示符。
within:限定匹配特定类型的连接点,当使用Spring AOP的时候,只能匹配方法执行的连接点;只可以使用包名进行匹配,比如within(com.yang.service..*)
this:用于限定AOP代理必须是指定类型的实例,用于匹配该对象的所有连接点。当使用SpringAOP的时候,只能匹配方法执行的连接点.比如this(com.yang.service.UserService)
target:用于限定目标对象必须是指定类型的实例,用于匹配该对象的所有连接点。当使用SpringAOP的时候,只能匹配方法执行的连接点。
args:用于对连接点的参数类型进行限制,要求参数类型是指定类型的实例。Spring AOP值能够匹配方法执行的连接点。
execution表达式的语法格式如下:
execution(
modifiers-pattern? 指定方法的修饰符,支持通配符,可以省略 Return-typepatterns 指定方法的返回值类型,支持通配符, 可以使用* 通配符匹配所有类型的返回值类型
declaring-type-pattern? 指定方法所属的类,支持通配符,可以省略
Name-pattern(param-pattern) 指定匹配的方法名,支持通配符,可以使用*匹配所有的方法,其中的param-pattern指的是参数类型,支持两种通配符,一种是*,表示一个任意类型的参数;另一个是..,表示的是0个或者是多个任意类型的参数
throws-pattern? 表示指定的方法声明抛出异常,支持通配符,可以省略)
通过方法签名定义切入点:
execution(public * *(..)) :匹配目标类所有的public方法
execution(* find*(..))
通过类定义切入点,通过包定义切入点,通过方法形参定义切入点
execution(* com.yang.service.UserService+.*(..)) +表示其接口还有其实现子类中的方法
execution(* com..*.yang.service.*(..))表示包括子包
同时可以使用组合表达式&& || !将多个切入点表达式组合起来。
二、基于Annotation配置的AOP
其实掌握了XML方式配置的AOP之后,转换成为Annotation方式是十分容易的。AspectJ是一个基于Java语言的AOP框架,他扩展了标准的Java,从语言层面上提供了更加强大的AOP功能。AspectJ是AOP的实现之一,对整套的AOP机制都有着很好的实现机制,所以不使用Spring也可以直接使用AspectJ进行切面编程。从Spring2开始,就已经将AspectJ集成在Spring中。AspectJ允许使用Annotation来定义切面(Aspect)、切入点(pointcut)、增强(Advice)。Spring框架根据这些Annotation来生成对应的AOP代理。
1.配置切面在Spring配置文件中需要添加
<aop:aspectj-autoproxy/>
增加上述配置之后,Spring会根据注解判断一个Bean是否使用了一个或者多个切面,然后自动生成相对应的AOP代理以及拦截器方法调用,并且确认Advice是否如期进行。这里使用注解的方式,需要增加两个AspectJ的类库aspectjweaver.jar&& aspectjrt.jar
2.声明切面
在创建的AspectBean类前面声明是切面,使用如下方式:
@Aspect
public class AspectBean{}
3.配置Advice
AspectJ有一下几种配置方法,这些注解的存留期是RetentionPolicy.RUNTIME,注解目标都是ElementType.METHOD
AspectJ提供的几种注解方式:
@Before 成员有value指定一个切入点表达式,也可以指定一个已经存在的切入点
@AfterReturning value、 returning 表示目标对象返回值绑定给增强的方法, pointcut会覆盖
@Around value切入点表达式
@AfterThrowing value 切入点表达式 pointcut覆盖掉value, throwing将抛出的异常绑定到增强的方法
@After value
4配置切入点
使用@Pointcut进行生命,一个切入点的声明有两个部分组成,包含名字和任意参数的签名和切入点表达式。
@Aspect
public class AspectBean {
//@Before(value="execution(* com.yang.service.UserService.*(..))")
@Pointcut("execution(* com.yang.service.UserService.*(..))")
private void crud(){}
@Before(value="crud")
public void checkAuth(){
System.out.println("AspectBean.checkAuth()");
}
}
源代码:
UserService.java
package com.yang.service;
public interface UserService {
public void del();
public void add();
public void update();
public Object select();
}
UserServiceImpl.java
package com.yang.service.impl;
import com.yang.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public void del() {
System.out.println("UserServiceImpl.del() function ");
}
@Override
public void add() {
System.out.println("UserServiceImpl.add() function ");
}
@Override
public void update() {
System.out.println("UserServiceImpl.update() function ");
}
@Override
public Object select() {
System.out.println("UserServiceImpl.select() function ");
return null;
}
}
AspectBean.java
import org.aspectj.lang.ProceedingJoinPoint;
//@Aspect
public class AspectBean {
//@Before(value="execution(* com.yang.service.UserService.*(..))")
//@Pointcut("execution(* com.yang.service.UserService.*(..))")
private void crud(){}
//@Before(value="crud")
public void checkAuth(){
System.out.println("AspectBean.checkAuth()");
}
public void release(){
System.out.println("AspectBean.release()");
}
public void log(Object result){
System.out.println("AspectBean.log()");
if(result==null){
System.out.println("database have result");
}else{
System.out.println("database has no result");
}
}
public void processException(Throwable ex){
System.out.println("Exception information:" + ex.getMessage());
}
public void proceedInTrans(ProceedingJoinPoint joinpoint) throws Throwable{
System.out.println("start transtraction");
joinpoint.proceed();
System.out.println("end transtraction");
}
}
bean.xml
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
default-lazy-init="true">
<aop:aspectj-autoproxy/>
<bean id="aspectBean" class=" com.yang.aspect.AspectBean"></bean>
<bean id="userService" class="com.yang.service.impl.UserServiceImpl"></bean>
<aop:config proxy-target-class="true">
<aop:aspect id="myadvice" ref="aspectBean">
<aop:before method="checkAuth" pointcut="execution(* com.yang.service.UserService.*(..))"/>
<aop:after-returning method="log" pointcut="execution(* com.yang.service.UserService.select(..))" returning="result"/>
<aop:after-throwing method="processException" pointcut="execution(* com.yang.service.UserService.*(..))" throwing="ex"/>
<aop:around method="proceedInTrans" pointcut="execution(* com.yang.service.UserService.*(..))"/>
<aop:after method="release" pointcut="execution(* com.yang.service.UserService.*(..))"/>
</aop:aspect>
</aop:config>
</beans>
TestMain.java
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//System.out.println("before");
UserService userService = (UserService) context.getBean("userService");
System.out.println("=======================================");
userService.add();
System.out.println("=======================================");
userService.select();
System.out.println("=======================================");
YangTengfei
2013.11.26
补充知识:
记得自己在S2SH框架整合的时候,遇到的一个问题,其实是因为自己对于前面知识掌握的不怎么到位,以至于在S2SH整合的时候因为一个小小的知识点的错误,而导致了我找了4个小时的错误才依旧是没有找出来。
先说一下自己的错误:在S2SH框架整合的时候,最后一步关于实现S2SH框架中的事务机制,我们使用的是Hibernate的HibernateTransactionManager,然后配置了事务的切入点:具体配置如下:
<!-- S2SH配置的 Hibernate 的事物管理器 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事务的Advice,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- 配置事务的详细定义 -->
<tx:attributes>
<tx:method name="add*" rollback-for="Exception"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 配置切入点信息,并且将它和切面整合 -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.yang.s2s.service.impl.*.*(..))"/>
</aop:config>
强敌出现:
在这个配置中,启动Tomcat服务器总是出错,然后就是各种错误说是dataSource出错,然后我们尝试各种方法总是找不到错误,悲了个剧,纠结了4个小时还是不可以。原因是我么配置的pointcut的表达式错误。
回顾配置这个的切入点的规范:
execution (
modifiers-pattern?
return-type-pattern
declaring-type-pattern?
Name-pattern(param-pattern)
throw-pattern?
)
其中的name-pattern * 表示包下的所有类,之后必须还有一个匹配方法,因为配置事务的基本单位是方法而不是类。所以需要修改成为 execution(* com.yang.s2s.service.impl.*Impl.*(..))表示的是任何返回值类型的 在com.yang.s2s.service.impl.包下的以Impl结尾的Class中的任意方法,其中参数也是任意的。
Add by YangTengfei
2013.12.02
Spring入门4.AOP配置深入的更多相关文章
- Spring入门3.AOP编程
Spring入门3.AOP编程 代码下载: 链接: http://pan.baidu.com/s/11mYEO 密码: x7wa 前言: 前面学习的知识是Spring在Java项目中的IoC或DJ,这 ...
- Spring 入门 web.xml配置详解
Spring 入门 web.xml配置详解 https://www.cnblogs.com/cczz_11/p/4363314.html https://blog.csdn.net/hellolove ...
- Spring入门篇——AOP基本概念
1.什么是AOP及实现方式 什么是AOP AOP:Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 主要 ...
- spring的注解AOP配置
package com.hope.service.impl;import com.hope.service.IAccountService;import org.aspectj.lang.annota ...
- Spring入门介绍-AOP(三)
AOP的概念 AOP是面向切面编程的缩写,它是一种编程的新思想.对我们经常提起的oop(面对对象编程)有一定的联系. AOP和OOP的关系 AOP可以说是oop的某一方便的补充,oop侧重于对静态的属 ...
- Spring课程 Spring入门篇 5-2 配置切面aspect
本节主要讲了在xml中配置切面的demo 1 解析 1.1 配置切面xml 1.2 配置切面xml 1.3 问:什么是动态代理? 2 代码演练 2.1 配置切面xml 1 解析 1.1 配置切面xml ...
- Spring入门之AOP篇
听了几节IT黑马营的SPRING课程,照着例程写了一个SPRING 中AOP的例子: 一.准备工作 下载复制或配置JAR包.图方便,我将下载的SPRING包都加上去了.另外还需要aspectj的两个 ...
- spring中使用aop配置事务
spring的事务配置有5种方式,这里记录其中的一种:基于tx/aop声明式事务配置 在之前spring aop介绍和示例这篇所附代码的基础上进行测试 一.添加save方法 1.在testDao类里添 ...
- Spring课程 Spring入门篇 5-3 配置切入点 pointcut
1 解析 1.1 xml常见的配置切入点写法 2 代码演练 2.1 xml配置切入点 1 解析 1.1 xml常见的配置切入点写法 2 代码演练 2.1 xml配置切入点 xml配置: <? ...
随机推荐
- python3.5实现购物车
一.购物车实现: 购物车功能: 用户登录:密码错误三次锁定账户. 商品列表分页显示:输入页码查看指定页数商品信息. 已购买商品列表:显示已购买的物品列表:可以模糊查询已购买的商品并在终端打印. 充值: ...
- 什么是“HTML”?HTML的“标记”是什么?
①文本标记语言 即HTML(Hypertext Markup Language),是用于描述网页文档的一种标记语言. ②HTML 标记标签 通常被称为 HTML 标签 (HTML tag). ③HTM ...
- Spark高级数据分析· 2数据分析
wget https://archive.ics.uci.edu/ml/machine-learning-databases/00210/donation.zip 数据清洗 cd /Users/eri ...
- 用74HC165读8个按键状态
源:用74HC165读8个按键状态 源:74LV165与74HC595 使用 74LV165说明: 74LV165是8位并行负载或串行输入移位寄存器,末级提供互补串行输出(Q7和Q7).并行负载(PL ...
- Python面试题之Python中type和object的关系
知乎上看到的提问: 两个是互为实例的关系,但不是互为子类的关系,只有type是object的子类,反之则不成立. 大牛说两者是蛋生鸡鸡生蛋的关系,但我还是不明白,有懂的麻烦解释一下, 希望不要给出外文 ...
- MVC中使用分部视图参数,改变分部视图连接样式
MVC中使用分部视图参数,改变分部视图连接样式! Controller代码 [ChildActionOnly] public ActionResult Navigator(int tag) { ret ...
- GSM900TCP/UDP连接
TCP发送:AT+CIPSTART="TCP","122.0.114.244",1001返回:OK CONNECT OK 发送: AT+CIPSEND > ...
- linux下nano中复制粘贴剪切的快捷键是什么
答: 1.复制:alt+6 2.剪切:ctrl+k 3.粘贴:ctrl+u 4.自由剪切: ctrl+6指定起始剪切位置,按上下左右键来选中内容,然后按下ctrl+k即可自由剪切 5.撤销: alt+ ...
- [洛谷P4918]信仰收集
题目背景 随着各种势力的迁入,守矢神社丧失了不少信仰现在,为了挽回香火日益惨淡的神社,八坂神奈子派遣神社的风祝早苗去人类村落收集信仰 题目描述 你可以将村落看成一个m个点的有向无环图(编号从1−m), ...
- [BZOJ2809]dispatching
Description 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级. ...