一个非常有趣的使用spring框架AOP例子

合集下载

Springboot纯注解Aop示例

Springboot纯注解Aop示例

Springboot纯注解Aop示例Spring Boot是一个基于Spring框架的快速开发框架,提供了一种简化Java应用程序开发和部署的方式。

AOP(Aspect-Oriented Programming)是一种面向切面编程的技术,可以通过在不改变原有代码的情况下,动态地将额外的逻辑横切到应用程序的各个模块中。

在Spring Boot中使用纯注解实现AOP,可以通过使用AspectJ注解来定义切面和通知,以及使用Spring AOP注解来实现横切逻辑的织入。

下面是一个示例,展示了如何在Spring Boot中使用注解实现AOP。

首先,我们需要在pom.xml文件中添加必要的依赖:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>``````javapublic class LoggingAspectpublic void controllerMethod}public void logMethodCall(JoinPoint joinPoint)String methodName = joinPoint.getSignature(.getName(;String className =joinPoint.getTarget(.getClass(.getSimpleName(;System.out.println("Calling method " + methodName + " of class " + className);}public void logMethodReturn(JoinPoint joinPoint, Object result)String methodName = joinPoint.getSignature(.getName(;String className =joinPoint.getTarget(.getClass(.getSimpleName(;System.out.println("Method " + methodName + " of class " + className + " returned " + result);}``````javapublic class SpringBootDemoApplicationpublic static void main(String[] args)}```现在,我们可以编写一个简单的Controller类来测试我们的AOP切面:```javapublic class GreetingControllerpublic String sayHellreturn "Hello, World!";}``````Calling method sayHello of class GreetingControllerMethod sayHello of class GreetingController returned Hello, World!```通过使用纯注解的方式,我们可以很方便地在Spring Boot应用程序中实现AOP功能。

SpringAOP的原理和应用场景

SpringAOP的原理和应用场景

SpringAOP的原理和应用场景SpringAOP(Aspect-Oriented Programming)是Spring框架中的一个重要组成部分,它提供了一种通过预定义的方式,将横切关注点(Cross-cutting Concerns)与业务逻辑进行解耦的机制。

本文将介绍SpringAOP的原理及其在实际应用场景中的应用。

一、SpringAOP的原理SpringAOP基于代理模式(Proxy Pattern)实现。

在SpringAOP中,通过生成与原始类(被代理类)具有相同接口的代理类,将横切逻辑编织到业务逻辑中。

在运行时,当调用代理类的方法时,会在方法执行前、后或异常抛出时插入相应的横切逻辑代码。

具体而言,SpringAOP使用了以下几个核心概念:1. 切面(Aspect):切面是横切逻辑的模块化单元,它包含了一组通知(Advice)和切点(Pointcut)。

2. 通知(Advice):通知定义了实际的横切逻辑代码,并规定了何时执行该代码。

SpringAOP提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。

3. 切点(Pointcut):切点指定了在哪些连接点(Join Point)上执行通知。

连接点可以是方法调用、属性访问等程序执行的点。

4. 连接点(Join Point):连接点是程序执行过程中的一个特定点,如方法调用前、方法调用后等。

通知通过切点来选择连接点。

5. 织入(Weaving):织入是将切面应用到目标对象,并创建代理对象的过程。

织入可以在编译时、类加载时或运行时进行。

二、SpringAOP的应用场景SpringAOP可应用于各种场景,用于解决跨越多个模块或类的横切关注点问题。

以下是一些常见的SpringAOP应用场景:1. 日志记录:通过在关键方法的前后插入日志代码,实现对系统运行状态的监控和记录。

SpringBootAop详解和多种使用场景

SpringBootAop详解和多种使用场景

SpringBootAop详解和多种使⽤场景前⾔aop⾯向切⾯编程,是编程中⼀个很重要的思想本篇⽂章主要介绍的是SpringBoot切⾯Aop的使⽤和案例什么是aopAOP(Aspect OrientedProgramming):⾯向切⾯编程,⾯向切⾯编程(也叫⾯向⽅⾯编程),是⽬前软件开发中的⼀个热点,也是Spring框架中的⼀个重要内容。

利⽤AOP可以对业务逻辑的各个部分进⾏隔离,从⽽使得业务逻辑各部分之间的耦合度降低,提⾼程序的可重⽤性,同时提⾼了开发的效率。

使⽤场景利⽤AOP可以对我们边缘业务进⾏隔离,降低⽆关业务逻辑耦合性。

提⾼程序的可重⽤性,同时提⾼了开发的效率。

⼀般⽤于⽇志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理。

使⽤场景为什么需要⾯向切⾯编程⾯向对象编程(OOP)的好处是显⽽易见的,缺点也同样明显。

当需要为多个不具有继承关系的对象添加⼀个公共的⽅法的时候,例如⽇志记录、性能监控等,如果采⽤⾯向对象编程的⽅法,需要在每个对象⾥⾯都添加相同的⽅法,这样就产⽣了较⼤的重复⼯作量和⼤量的重复代码,不利于维护。

⾯向切⾯编程(AOP)是⾯向对象编程的补充,简单来说就是统⼀处理某⼀“切⾯”的问题的编程思想。

如果使⽤AOP的⽅式进⾏⽇志的记录和处理,所有的⽇志代码都集中于⼀处,不需要再每个⽅法⾥⾯都去添加,极⼤减少了重复代码。

技术要点通知(Advice)包含了需要⽤于多个应⽤对象的横切⾏为,完全听不懂,没关系,通俗⼀点说就是定义了“什么时候”和“做什么”。

连接点(Join Point)是程序执⾏过程中能够应⽤通知的所有点。

切点(Poincut)是定义了在“什么地⽅”进⾏切⼊,哪些连接点会得到通知。

显然,切点⼀定是连接点。

切⾯(Aspect)是通知和切点的结合。

通知和切点共同定义了切⾯的全部内容——是什么,何时,何地完成功能。

引⼊(Introduction)允许我们向现有的类中添加新⽅法或者属性。

SpringAOP示例与实现原理总结——传统springaop、基于切面注入、基于@Asp。。。

SpringAOP示例与实现原理总结——传统springaop、基于切面注入、基于@Asp。。。

SpringAOP⽰例与实现原理总结——传统springaop、基于切⾯注⼊、基于@Asp。

⼀、代码实践1)经典的Spring Aop经典的spring aop,是基于动态代理技术的。

实现⽅式上,最常⽤的是实现MethodInterceptor接⼝来提供环绕通知,创建若⼲代理,然后使⽤ProxyBeanFactory配置⼯⼚bean,⽣成拦截器链,完成拦截。

⽰例如下:1package demo.spring;23import org.aopalliance.intercept.MethodInterceptor;4import org.aopalliance.intercept.MethodInvocation;5import org.junit.Test;6import org.junit.runner.RunWith;7import org.springframework.beans.factory.annotation.Autowired;8import org.springframework.test.context.ContextConfiguration;9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;1011 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration("classpath:spring-config.xml")13public class TraditionalSpringAopDemo {14 @Autowired15private Service proxy;1617 @Test18public void test() {19 proxy.execute("hello world!");20 }21 }2223interface Service {24void execute(String str);25 }2627class ServiceImpl implements Service {28 @Override29public void execute(String str) {30 System.out.println("execute invoke: " + str);31 }32 }3334class Interceptor1 implements MethodInterceptor {35 @Override36public Object invoke(MethodInvocation methodInvocation) throws Throwable {37 System.out.println("interceptor1,before invoke");38 Object ret = methodInvocation.proceed();39 System.out.println("interceptor1,after invoke");40return ret;41 }42 }4344class Interceptor2 implements MethodInterceptor {45 @Override46public Object invoke(MethodInvocation methodInvocation) throws Throwable {47 System.out.println("interceptor2,before invoke");48 Object ret = methodInvocation.proceed();49 System.out.println("interceptor2,after invoke");50return ret;51 }52 }xml⽂件配置:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:context="/schema/context"5 xmlns:aop="/schema/aop"6 xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /schema/context /schema/context/sprin 78<context:component-scan base-package="demo.spring"/>910<bean class="demo.spring.ServiceImpl" id="service"></bean>11<bean class="demo.spring.Interceptor1" id="interceptor1"></bean>12<bean class="demo.spring.Interceptor2" id="interceptor2"></bean>13<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="proxy">14<property name="target" ref="service"/>15<property name="interceptorNames">16<list>17<value>interceptor1</value>18<value>interceptor2</value>19</list>20</property>21</bean>22</beans>结果:interceptor1,before invokeinterceptor2,before invokeexecute invoke: hello world!interceptor2,after invokeinterceptor1,after invoke可以看到拦截链的执⾏过程与拦截器顺序的关系。

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

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

Spring之注解实现aop(⾯向切⾯编程)1:Aop(aspect object programming)⾯向切⾯编程,名词解释:1.1:功能:让关注点代码与业务逻辑代码分离1.2:关注点重复代码就叫做关注点1.3:切⾯关注点形成的类,就叫做切⾯(类)⾯向切⾯编程,就是指对很多功能都有的重复代码抽取,再在运⾏的时候往业务⽅法上动态植⼊"切⾯类代码";1.4:切⼊点执⾏⽬标对象⽅法,动态植⼊切⾯代码可以通过切⼊点表达式,指定拦截那些类的那些⽅法,给指定的类在运⾏的时候植⼊切⾯类代码;2:注解⽅式实现aop编程2.1:开发步骤(1):先引⼊aop相关的jar⽂件spring-aop-3.2.5.RELEASE.jar【去spring3.2源码⾥⾯找】aopalliance.jar【去spring2.5源码/lib/aopalliance⽂件⾥⾯找】aspectjweaver.jar【去spring2.5源码/lib/aspectj⽂件⾥⾯找】或者【aspectj-1.8.2/lib/aspectjweaver.jar】aspectjrt.jar【去spring2.5源码/lib/aspectj⽂件⾥⾯找】或者【aspectj-1.8.2/lib/aspectjrt.jar】 《注意:⽤到的spring2.5版本的jar本舰,如果⽤jd1.7版本可能会出现问题,需要升级以下aspectj组件,即使⽤aspectj-1.8.2版本中提供的jar⽂件aspectjweaver.jar和aspectjrt.jar》(2)bean.xml中引⼊aop名称空间 技巧:找到⽂件spring-framework-3.2.5.RELEASE/docs/spring-framework-reference/htmlsingle 打开index.html搜索xmlns:aop然后找到下⾯红⾊三句话,分别拷贝到bean.xml中 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xmlns:aop="/schema/aop" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /schema/aop /schema/aop/spring-aop.xsd"> 拷贝之后的bean.xml如下所⽰:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:p="/schema/p"5 xmlns:context="/schema/context"6 xmlns:aop="/schema/aop"7 xsi:schemaLocation="8 /schema/beans9 /schema/beans/spring-beans.xsd10 /schema/context11 /schema/context/spring-context.xsd12 /schema/aop13 /schema/aop/spring-aop.xsd">1415</beans> (3):bean.xml中开启aop注解扫描,如下配置所⽰:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:p="/schema/p"5 xmlns:context="/schema/context"6 xmlns:aop="/schema/aop"7 xsi:schemaLocation="8 /schema/beans9 /schema/beans/spring-beans.xsd10 /schema/context11 /schema/context/spring-context.xsd12 /schema/aop13 /schema/aop/spring-aop.xsd">1415<!-- 开启注解扫描 -->16<context:component-scan base-package="com.bie.aop"></context:component-scan>1718<!-- 开启aop注解⽅式,默认为false -->19<aop:aspectj-autoproxy></aop:aspectj-autoproxy>2021</beans> (4):开始写⼀个切⾯类,源码如下所⽰:1package com.bie.aop;23import ng.annotation.After;4import ng.annotation.Aspect;5import ng.annotation.Before;6import ng.annotation.Pointcut;7import ponent;8910/**11* @author BieHongLi12* @version创建时间:2017年3⽉28⽇下午9:10:4313* @Aspect:指定当前类为切⾯类14*/15 @Component //加⼊到IoC容器16 @Aspect //指定当前类为切⾯类17public class Aop {1819//指定切⼊点表达式,拦截那些⽅法,即为那些类⽣成代理对象20//@Pointcut("execution(* erDao.save(..))") ..代表所有参数21//@Pointcut("execution(* erDao.*())") 指定所有的⽅法22//@Pointcut("execution(* erDao.save())") 指定save⽅法2324 @Pointcut("execution(* erDao.*(..))")25public void pointCut(){2627 }2829 @Before("pointCut()")30public void begin(){31 System.out.println("开启事务");32 }3334 @After("pointCut()")35public void close(){36 System.out.println("关闭事务");37 }3839 } (5):写好切⾯类就可以写执⾏⽬标对象⽅法,接⼝和实现类如下所⽰: 1package com.bie.aop;23/**4* @author BieHongLi5* @version创建时间:2017年3⽉28⽇下午9:09:296*7*/89public interface IUserDao {1011public void save();12 }1package com.bie.aop;234import ponent;56/**7* @author BieHongLi8* @version创建时间:2017年3⽉28⽇下午9:09:539* ⽬标对象10*/11 @Component12public class UserDao implements IUserDao{1314 @Override15public void save() {16 System.out.println("..核⼼业务--核⼼业务..");17 }181920 } (6):最后就可以进⾏进⾏测试了,源码如下所⽰:1package com.bie.aop;23import org.junit.Test;4import org.springframework.context.ApplicationContext;5import org.springframework.context.support.ClassPathXmlApplicationContext;67/**8* @author BieHongLi9* @version创建时间:2017年3⽉28⽇下午9:13:1810*11*/12public class AopTest {1314 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");1516//⽬标对象有实现接⼝,spring会⾃动选择"jdk代理【动态代理】"17//动态代理的标识:class com.sun.proxy.$Proxy1018 @Test19public void test01(){20 IUserDao dao = (IUserDao) ac.getBean("userDao");21 System.out.println(dao.getClass());22 dao.save();23 }242526//class com.bie.aop.OrderDao$$EnhancerByCGLIB$$4952a60a27//⽬标对象没有实现接⼝,spring会⽤"cglib代理哦"28 @Test29public void testCglib(){30 OrderDao dao = (OrderDao) ac.getBean("orderDao");31 System.out.println(dao.getClass());32 dao.save();33 }34 } 3:⼼得体会和报错解决: 3.1:虽然案例很简单很简单,但是我花了三四个⼩时,为什么呢!我⽤junit测试spring写的注解实现aop(⾯向切⾯编程)。

AOP-2实例(SpringBoot注解方式)

AOP-2实例(SpringBoot注解方式)

AOP-2实例(SpringBoot注解⽅式) 1、创建Spring Boot项⽬ 创建⼀个Spring Boot 项⽬,然后pom中引⼊web 模块与AOP相关依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.0.1.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency>其中:aspectjweaver是与aspectj相关的包,⽤来⽀持切⾯编程的;aspectjweaver是aspectj的织⼊包;2、实现⼀个web请求,数据通过接⼝获取(使⽤POJO类传参与返回值)@RestController@RequestMapping("/aop")public class AopController {@Autowiredprivate AopService aopService;@GetMapping(value = "getResult")public ResultVO sayHello(ParamVO paramVO) {ParamDTO paramDTO = new ParamDTO();BeanUtils.copyProperties(paramVO, paramDTO);ResultDTO resultDTO = aopService.getResult(paramDTO);ResultVO resultVO = new ResultVO();BeanUtils.copyProperties(resultDTO, resultVO);return resultVO;}}列出⼀个POJO类,其他类似。

spring基于注解配置aop案例

spring基于注解配置aop案例

spring基于注解配置aop案例spring基于注解配置aop案例1、导⼊jar包基于maven项⽬<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.14</version></dependency>2、编写实体类package com.yl.bean;import java.io.Serializable;/*** ⽤户实体类*/public class User implements Serializable {private Integer id;private String username;private String password;public User() {}public User(Integer id, String username, String password) {this.id = id;ername = username;this.password = password;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {ername = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}}3、编写业务层业务层接⼝package com.yl.service;/*** ⽤户业务层接⼝*/public interface IUserService {/*** 查询⽤户*/public void queryUser();}业务层接⼝实现类package com.yl.service.impl;import com.yl.dao.IUserDao;import com.yl.service.IUserService;import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** ⽤户业务层接⼝实现类*/@Service("userService")public class IUserServiceImpl implements IUserService { @Resource(name = "userDao")private IUserDao iUserDao;//⽤户持久层对象/*** 查询⽤户*/@Overridepublic void queryUser() {// int i=1/0;iUserDao.queryUser();}}4、编写持久层持久层接⼝package com.yl.dao;/*** ⽤户持久层接⼝*/public interface IUserDao {/*** 查询⽤户*/public void queryUser();}持久层接⼝实现类package com.yl.dao.impl;import com.yl.dao.IUserDao;import org.springframework.stereotype.Repository;/*** ⽤户持久层接⼝实现类*/@Repository("userDao")public class IUserDaoImpl implements IUserDao {/*** 查询⽤户*/@Overridepublic void queryUser() {System.out.println("查询成功");}}5、编写通知类package rm;import ng.ProceedingJoinPoint;import ng.annotation.*;import ponent;/*** spring通知类*/@Component("userInform")@Aspect//指定当前类为切⾯public class UserInform {/***配置通⽤切⼊点*/@Pointcut("execution(* com.yl.service.impl.IUserServiceImpl.*())")private void pt1(){}/*** 前置通知*/@Before("pt1()")public void beforeInform(){System.out.println("开启事务");}/*** 后置通知*/@AfterReturning("execution(* com.yl.service.impl.IUserServiceImpl.*())")public void afterInform(){System.out.println("提交事务");}/*** 异常通知*/@AfterThrowing("execution(* com.yl.service.impl.IUserServiceImpl.*())")public void throwInform(){System.out.println("异常通知");}/*** 环绕通知*//*public void aroundInform(ProceedingJoinPoint pjp){System.out.println("前置通知");try {pjp.proceed();System.out.println("后置通知");} catch (Throwable throwable) {System.out.println("异常通知");}finally {System.out.println("最终通知");}}*/}6、配置⽂件<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="/schema/aop"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/aop/schema/aop/spring-aop.xsd/schema/contexthttps:///schema/context/spring-context.xsd"><!--指定spring要扫描的包--><context:component-scan base-package="com.yl"></context:component-scan> <!--开启spring对注解aop的⽀持--><aop:aspectj-autoproxy/></beans>7、测试package com.yl.ui;import com.yl.service.IUserService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 测试类*/public class MainTest {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml"); IUserService userService= (IUserService) applicationContext.getBean("userService");userService.queryUser();}}8、不使⽤xml⽅式⽤配置类替代xml配置⽂件@Configuration@ComponentScan(basePackages="com.itheima")@EnableAspectJAutoProxypublic class SpringConfiguration {}。

应用Spring框架中的AOP Arround类型的通知组件实现监控项目性能的应用实例

应用Spring框架中的AOP Arround类型的通知组件实现监控项目性能的应用实例
(2)编程该 ProfileInterceptor 拦截器 package com.px1987.webbank.account.intercept; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class ProfileInterceptor implements MethodInterceptor { public ProfileInterceptor() { } public Object invoke(MethodInvocation oneMethodInvocation) throws
userPassWord=?";
try{
try {
java.sql.PreparedStatement
pstmt
=
con.prepareStatement(select_SqlStatement,
杨教授工作室,版权所有,盗版必究, 1/6 页
杨教授工作室 精心创作的优秀程序员 职业提升必读系列资料
oneUserInfoPOReturn.setUserPassWord(rs.getString("userPassWord"));
}
catch (SQLException e){
System.out.println(e.getMessage());
}
}
finally{
try {
con.close();
System.out.println("方法执行所花费的时间为"+usedTime+"秒");
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一个非常有趣的使用spring框架AOP例子接触spring有一段时间了,不过都是看的多,写的少,工作忙,公司也不准备用。

自己写过一些小东西用到,也只用到了BeanFactory组装对象,JdbcTemplate代替jdbc,事务管理。

东抓一把,西抓一把,没形成系统。

最近也在看spring自带的reference,一时手痒,写了个AOP的创建advice的例子,比之单纯地使用TransationProxyFactoryBean 对AOP的理解又深入了点,打算看看它的源代码,基于CGLIB的实现对类的代理不了解,倒是好奇它如何实现对接口的代理??也就是利用J2SE的动态代理技术。

例子如下:讲述一间书店开始打折促销,规则是每一名顾客只能买一本书,而且已经脱销了。

你可以去掉TestAdvice里的注释看看各种运行结果,具体就不解释咯,在代码注释里。

首先,你必须对增强(advice)有所了解,增强就是在特定连接点执行的动作。

advice contains the logic of your aspect。

增强,分为4类:前增强(before)在连接点之前调用后增强(after)在连接点执行之后调用、环绕增强(around)完整控制整个方法流程,必须调用MethodInvocation的proceed促使真实操作发生异常增强针对某个异常抛出时调用书店,一个buyBook业务:package com.denny_blue.springdemo.aop;public interface BuyBook {public void buyBook(String customer,String book)throws NoThisBookException;}实现此接口的一个业务对象,如果顾客要买就抛出NoThisBookException异常。

package com.denny_blue.springdemo.aop;public class MyBuyBook implements BuyBook {public void buyBook(String customer,String book)throws NoThisBookException{if(book.equals(""))throw new NoThisBookException("对不起,没有"+book+"存货了!");System.out.println(customer+",你好,你已经购买了一本"+book+"!");}}自定义两个异常类,其中NoThisBookException被抛出时将触发MyThrowsAdvice调用://NoThisBookException.javapackage com.denny_blue.springdemo.aop;public class NoThisBookException extends RuntimeException {public NoThisBookException(String msg){super(msg);}}//BuyBookException.javapackage com.denny_blue.springdemo.aop;public class BuyBookException extends RuntimeException {public BuyBookException(String msg){super(msg);System.out.println(msg);}}OK,接下来就是各类增强了,前增强,在业务方法buyBook之前调用,显示欢迎信息:package com.denny_blue.springdemo.aop;import ng.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class MyBeforeAdvice implements MethodBeforeAdvice {public void before(Method arg0, Object[] arg1, Object target)throws Throwable {String customer=(String)arg1[0]; //第2个参数组就是被增强的方法传入的参数,本例中即customer,bookSystem.out.println("欢迎光临!"+customer+"!"); //显示欢迎信息!,在buyBook方法前调用}}然后是后增强,当顾客已经买了书之后,显示欢送信息:package com.denny_blue.springdemo.aop;import ng.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class MyAfterAdvice implements AfterReturningAdvice {public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {String customer=(String)arg2[0]; //同前增强一样,参数组3为传入参数,具体见spring docSystem.out.println("欢迎下次再来!"+customer+"!"); //显示欢送信息!}} 来源:考试大-Java认证OK,有了上面两个advice我们就能提供给顾客很好的服务态度了,等等?我们还有规则没实现,不是说一名顾客只能买一本书吗?OK,我们用环绕增强来解决,在环绕增强中保存一个HashSet,判断顾客是否来过,来过就抛出一个异常,没来过再放入此Set中:package com.denny_blue.springdemo.aop;import java.util.HashSet;import java.util.Set;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class MyAroundAdvice implements MethodInterceptor {private Set customers=new HashSet(); //保存购过书的顾客信息public Object invoke(MethodInvocation invocation) throws Throwable {String customer=(String)invocation.getArguments()[0];if(customers.contains(customer)){throw new BuyBookException("对不起,一名顾客只能买一本打折书!");}Object result=invocation.proceed(); //调用MyBuyBook中的buyBook方法,即真实操作customers.add(customer);return result;}}好了,最后一个,异常增强,当顾客要买时,我们的书店没书了,请仓库部门赶快订货!!package com.denny_blue.springdemo.aop;import org.springframework.aop.ThrowsAdvice;public class MyThrowsAdvice implements ThrowsAdvice {public void afterThrowing(NoThisBookException e){ //可以定义多个方法,只要传入的参数是不同异常System.out.print("通知仓库,赶紧加订书!");}}好了没?还没,我们需要一个XML文件来组装这些对象,来代理业务接口,完整的beans.xml如下,各元素的含义请自己查看spring reference?xml version="1.0" encoding="UTF-8"?>com.denny_blue.springdemo.aop.BuyBookmyBeforeAdvicemyAfterAdvicemyAroundAdvicemyThrowsAdvice我们先声明所有的bean,通过确定将要被增强的目标对象(target),我们可以很容易地替换这个目标对象,只要它实现业务接口。

代理的接口通过:com.denny_blue.springdemo.aop.BuyBook设定,然后是要用到一系列增强,注意,顺序是很有影响的!你可以尝试着改变顺序看看结果:)myBeforeAdvicemyAfterAdvicemyAroundAdvicemyThrowsAdvice一切准备好了,我们来测试吧,GO GO GOpackage test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext; import com.denny_blue.springdemo.aop.BuyBook;public class TestAdvice {public static void main(String args[]){ApplicationContext ctx=new FileSystemXmlApplicationContext("/src/beans.xml");//我的beans.xml放在项目下的src目录,eclipse环境下,请自己调整BuyBook buybook=(BuyBook)ctx.getBean("buyBook");buybook.buyBook("jordan","<深入浅出hibernate>");// buybook.buyBook("dennis",""); //去掉注释即可观察异常增强// buybook.buyBook("jordan","<深入浅出hibernate>"); //去掉注释即可观察环绕增强}}。

相关文档
最新文档