spring03 AOP、各种通知、一/多个切面例子
来源:互联网 发布:阿里云华南地区是哪里 编辑:程序博客网 时间:2024/06/03 21:58
一、 springAOP
1、作用: 使得事务、日志、安全性框架、权限、目标方法之间完全是松耦合的
2、组成
1、切面: 事务、日志、安全性框架、权限等都是切面
2、通知: 切面中的方法就是通知
3、目标类
4、切入点 只有符合切入点,才能让通知和目标方法结合在一起
5、织入: 形成代理对象的方法的过程
注:代理对象的方法就是通知和目标方法的结合体
3、相对于动态代理,省略了写拦截器的过程
4、切入点表达式详解
5、springAOP的具体加载步骤:
1、当spring容器启动的时候,加载了spring的配置文件
2、为配置文件中所有的bean创建对象
3、spring容器会解析aop:config的配置
解析切入点表达式,用切入点表达式和纳入spring容器中的bean做匹配
如果匹配成功,则会为该bean创建代理对象,代理对象的方法=目标方法+通知
如果匹配不成功,不会创建代理对象
4、在客户端利用context.getBean获取对象时,如果该对象有代理对象则返回代理对象,
如果无代理对象,则返回目标对象
5、如果目标类没有实现接口,则spring容器会采用cglib的方式产生代理对象,
如果实现了接口,会采用jdk的方式
6、各种通知详解
1、前置通知
1、在目标方法执行之前执行
2、无论目标方法是否抛出异常,都执行,因为在执行前置通知的时候,目标方法还没有执行,还没有遇到异常
例:
------------------------------------------------------------------------------
<aop:before method="beginTransaction" pointcut-ref="perform"/>
// 前置通知
public void beginTransaction(){
System.out.println("before inform");
this.transaction = sessionFactory.getCurrentSession().beginTransaction();
}
------------------------------------------------------------------------------
2、后置通知
1、在目标方法执行之后执行
2、当目标方法遇到异常,后置通知将不再执行
3、后置通知可以接受目标方法的返回值,但是必须注意:
后置通知的参数的类型为Object,且名称和配置文件中returning="var"的值是一致的
例:
------------------------------------------------------------------------------
不带参数的
<aop:after-returning method="commit" pointcut-ref="perform" />
// 后置通知
public void commit(){
System.out.println("after return inform");
this.transaction.commit();
}
// 不带返回值的目标方法
public void savePerson(Person person) {
sessionFactory.getCurrentSession().save(person);
}
带参数的
<aop:after-returning method="commit" pointcut-ref="perform" returning="var"/>
public void commit(Object var){
System.out.println("after return inform");
System.out.println(var);
this.transaction.commit();
}
// 带返回值的目标方法
public String savePerson(Person person) {
//int i = 1/0;
System.out.println("目标方法");
return "返回值";
}
------------------------------------------------------------------------------
3、最终通知:
1、在目标方法执行之后执行
2、无论目标方法是否抛出异常,都执行,因为相当于finally
例:
------------------------------------------------------------------------------
<aop:after method="fianllyMethod" pointcut-ref="perform"/>
public void fianllyMethod(){
System.out.println("finally inform");
}
------------------------------------------------------------------------------
4、异常通知
1、接受目标方法抛出的异常信息
2、步骤
在异常通知方法中有一个参数Throwable ex
在配置文件中
<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
注: throwing也要和切面中的异常通知的类型为Throable的参数名称保持一致
例:
-------------------------------------------------------------------------------
<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
public void throwingMethod(Throwable ex){
System.out.println(ex.getMessage());
}
// 目标类
public void savePerson(Person person) {
int i = 1/0;
sessionFactory.getCurrentSession().save(person);
}
-------------------------------------------------------------------------------
5、环绕通知
1、环绕通知可以控制目标方法的执行
方式: 在环绕通知中加一个参数:
org.aspectj.lang.JoinPoint包中的ProceedingJoinPoint joinPoint
然后在环绕通知中显示调用ProceedingJoinPoint的proceed()方法,,则执行目标方法
2、同时,各种通知若加JoinPoint参数(org.aspectj.lang.JoinPoint包),还可以获取目标方法的信息
例:
-------------------------------------------------------------------------------
不调用目标方法:
<aop:around method="aroundMethod" pointcut-ref="perform" />
public void aroundMethod(){
System.out.println("around inform");
}
// 目标方法 注: 此时未调用目标方法
public String savePerson(Person person) {
System.out.println("目标方法");
return "返回值";
}
调用目标方法:
<aop:around method="aroundMethod" pointcut-ref="perform" />
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
joinPoint.proceed(); // 显示的调用目标方法的执行,可以控制目标方法是否执行
System.out.println("around inform with targetMethod");
System.out.println("目标方法的方法名:"+joinPoint.getSignature().getName());
}
// 目标方法: 注: 此时调用了目标方法
public String savePerson(Person person) {
System.out.println("目标方法");
return "返回值";
}
-------------------------------------------------------------------------------
7、例1: 一个切面
--------------------------------------------------------------------------------
public class Person implements Serializable {
private Long pid;
private String pname;
private String psex;
}
// 接口
public interface PersonDao {
public void savePerson(Person person);
}
// 目标类
public class PersonDaoImpl extends HibernateUtil implements PersonDao {
@Override
public void savePerson(Person person) {
sessionFactory.getCurrentSession().save(person);
}
}
// 切面
public class MyTransaction extends HibernateUtil{
private Transaction transaction;
// 通知
public void beginTransaction(){
this.transaction = sessionFactory.getCurrentSession().beginTransaction();
}
// 通知
public void commit(){
this.transaction.commit();
}
}
配置文件:
<!-- AOP 导入目标类,导入切面 -->
<bean id="personDao" class="cn.itcast.spring.aop.PersonDaoImpl"></bean>
<bean id="myTransaction" class="cn.itcast.spring.aop.MyTransaction"></bean>
<!-- AOP 的配置 -->
<aop:config>
<!-- 切入点表达式 里面含有目标方法 -->
<aop:pointcut expression="execution(* cn.itcast.spring.aop.PersonDaoImpl.*(..))" id="perform"/>
<!-- 声明切面 -->
<aop:aspect ref="myTransaction">
<!-- 声明通知及其触发时间 -->
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<aop:after-returning method="commit" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
测试:
public class PersonTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext(
"cn/itcast/spring/aop/applicationContext.xml");
// 注: 此处得到的是代理对象
PersonDao personDao = (PersonDao) context.getBean("personDao");
Person person = new Person();
person.setPname("aaa");
person.setPsex("男");
personDao.savePerson(person);
}
}
--------------------------------------------------------------------------------
例1: 多个切面
--------------------------------------------------------------------------------
目标类:
public class SalaryManagerImpl {
public void show(){
System.out.println("目标方法:查看工资");
}
}
切面1:
public class Logger {
public void logger(){
System.out.println("logger");
}
}
切面2:
public class Security {
public void security(){
System.out.println("security");
}
}
切面3:
public class Privilege {
private String access;
// set/get属性
public void hasAccess(ProceedingJoinPoint joinPoint) throws Throwable{
if(this.access.equals("admin")){
joinPoint.proceed();
}else{
System.out.println("对不起,您没有权限");
}
}
}
配置文件:
<bean id="salaryManager" class="cn.itcast.spring.aop.aspeces.SalaryManagerImpl"></bean>
<bean id="logger" class="cn.itcast.spring.aop.aspeces.Logger"></bean>
<bean id="security" class="cn.itcast.spring.aop.aspeces.Security"></bean>
<bean id="privilege" class="cn.itcast.spring.aop.aspeces.Privilege">
<property name="access" value="admin1"></property>
</bean>
<aop:config>
<aop:pointcut expression="execution(
* cn.itcast.spring.aop.aspeces.SalaryManagerImpl.*(..))" id="perform"/>
<aop:aspect ref="logger">
<aop:before method="logger" pointcut-ref="perform"/>
</aop:aspect>
<aop:aspect ref="security">
<aop:before method="security" pointcut-ref="perform"/>
</aop:aspect>
<aop:aspect ref="privilege">
<aop:around method="hasAccess" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
测试:
public class SalaryTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("
cn/itcast/spring/aop/aspeces/applicationContext.xml");
SalaryManagerImpl proxy = (SalaryManagerImpl) context.getBean("salaryManager");
proxy.show();
}
}
--------------------------------------------------------------------------------
8、例:统一的错误异常处理
--------------------------------------------------------------------------------
public class PersonAction {
private PersonService personService = new PersonServiceImpl();
// set/get属性
public String savePerson() throws Exception{
this.personService.savePerson();
return null;
}
}
public interface PersonService {
public void savePerson() throws Exception;
}
public class PersonServiceImpl implements PersonService {
PersonDao personDao = new PersonDaoImpl();
// set/get属性
@Override
public void savePerson() throws Exception {
this.personDao.savePerson();
throw new RuntimeException("service层异常");
}
}
public interface PersonDao {
public void savePerson() throws Exception;
}
public class PersonDaoImpl implements PersonDao {
@Override
public void savePerson() throws Exception{
System.out.println("save person daoImpl");
throw new RuntimeException("dao层异常");
}
}
public class MyException {
public void myException(Throwable ex){
System.out.println(ex.getMessage());
}
}
配置文件:
<bean id="personDao" class="cn.itcast.dao.impl.PersonDaoImpl"></bean>
<bean id="personService" class="cn.itcast.service.impl.PersonServiceImpl">
<property name="personDao">
<ref bean="personDao"/>
</property>
</bean>
<bean id="personAction" class="cn.itcast.action.PersonAction">
<property name="personService">
<ref bean="personService"/>
</property>
</bean>
<bean id="myException" class="cn.itcast.myException.MyException"></bean>
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.service.impl.*.*(..))" id="perform"/>
<aop:aspect ref="myException">
<aop:after-throwing method="myException" pointcut-ref="perform" throwing="ex"/>
</aop:aspect>
</aop:config>
测试:
public class UnionExceptionTest {
@Test
public void test() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("
applicationContext.xml");
PersonAction personAction = (PersonAction) context.getBean("personAction");
personAction.savePerson();
}
}
--------------------------------------------------------------------------------
9、 springAOP注解的形式
--------------------------------------------------------------------------------
public class Person implements Serializable {
private Long pid;
private String pname;
private String psex;
// set/get属性
}
public interface PersonDao {
public void savePerson(Person person);
}
@Repository("personDao")
public class PersonDaoImpl extends HibernateUtil implements PersonDao {
@Override
public void savePerson(Person person) {
sessionFactory.getCurrentSession().save(person);
}
}
/**
@Aspect相当于:
<aop:config></aop:config>
*/
// 切面
@Component("myTransaction")
@Aspect
public class MyTransaction extends HibernateUtil{
private Transaction transaction;
/**
@Pointcut("execution(* cn.itcast.spring.aop.annotation.PersonDaoImpl.*(..))")相当于
<aop:pointcut expression="execution(* cn.itcast.spring.aop.annotation.PersonDaoImpl.*(..))" id="perform"/>
*/
@Pointcut("execution(* cn.itcast.spring.aop.annotation.PersonDaoImpl.*(..))")
private void perform(){} // 方法签名,返回值必须是void,并且方法的修饰符最好是private
// 前置通知
/**
@Before("perform()")相当于:
<aop:before method="beginTransaction" pointcut-ref="perform"/>
*/
@Before("perform()")
public void beginTransaction(){
this.transaction = sessionFactory.getCurrentSession().beginTransaction();
}
// 后置通知
/**
@AfterReturning(value="perform()",returning="var")相当于:
<aop:after-returning method="commit" pointcut-ref="perform" returning="var"/>
*/
@AfterReturning(value="perform()",returning="var")
public void commit(Object var){
this.transaction.commit();
}
}
配置文件:
<!--
把目标类和切面纳入到spring容器中管理,启动类扫描机制
-->
<context:component-scan base-package="cn.itcast.spring.aop.annotation"/>
<!-- 启动AOP的注解解析器 然后再在切面中写注解来代替配置信息 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
测试:
public class PersonTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("
cn/itcast/spring/aop/annotation/applicationContext.xml");
PersonDao personDao = (PersonDao) context.getBean("personDao");
Person person = new Person();
person.setPname("bbb");
person.setPsex("男");
personDao.savePerson(person);
}
}
--------------------------------------------------------------------------------
0 0
- spring03 AOP、各种通知、一/多个切面例子
- Spring AOP用到的切面,通知例子
- Spring03-AOP
- spring(AOP)多个切面
- Spring AOP 各种通知
- Aop 通知例子
- AOP中的概念通知、切点、切面、
- Spring AOP 切面与通知【Spring 入门】
- spring aop事务通知(切面异常处理)
- Spring学习(九)-AOP切面通知
- AOP中的概念通知、切点、切面
- 面向切面编程(AOP)各种麻烦的验证一键搞定
- Spring面向切面(AOP)的例子
- spring(AOP) 各种通知概念
- spring aop 通知简单例子
- Spring03
- 一个目标类对应多个切面的例子
- spring03 3幅图让你了解Spring AOP
- MyCat中ER表子表批量插入效率低的解决方案
- 从ICLassFactory 为 CLSID的COM组建创建实例失败 c001f011
- Numpy:基础
- IOS学习日志(Controller)1.4
- ones,zeros,size用法总结
- spring03 AOP、各种通知、一/多个切面例子
- 深度学习入门资源索引
- 阿里云服务器Ubuntu安装mysql
- 从ZooKeeper源代码看如何实现分布式系统(一)概述
- java 内部类 和 匿名内部类
- lingo求解最短路和最大流问题
- spring04 数据库操作 spring+jdbc/hibernate 及其声明式事务处理
- IE已限制此网页运行可以访问计算机的脚本或ActiveX控件,如何去除这个
- SAP CO TCODE