Spring_api方式实现aop
第一步:
public interface UserService {
public void add();
public void update(int a);
public void delete();
public void search();
}
第二步:
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加用户");
}
@Override
public void update(int a) {
System.out.println("修改用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void search() {
System.out.println("查询用户");
}
第三步:实现MethodBeforeAdvice的接口,Spring框架当中为我们提供了很多中通知。
public class Log implements MethodBeforeAdvice{
/**
* @param method 被调用方法对象
* @param args 被调用的方法的参数
* @param target 被调用的方法的目标对象
* */
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getNa me()+"方法被执行");
}
}
第四步:配置beans.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"
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="userService" class="com.spring.service.impl.UserServiceImpl"/>
<!-- 这个切面也要配置成bean-->
<bean id="log" class="com.spring.advice.Log"/>
<aop:config>
<!--切入点,需要告诉方法在什么去执行
expression="execution(* com.spring.service.impl.*.*(..))"
第一个* 表示所有的返回值,然后就是包名
第二个*表示所有的类对象
第三个*表示类对象所有的方法
第四个*表示所有方法下面的带参数的方法或者是不带参数的方法
-->
<aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>
<!-- 在所有的方法中都切入前置通知-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
</aop:config>
</beans>
第五步:测试:
package com.spring.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.UserService;
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService)ac.getBean("userService");
userService.update(2);
userService.add();
}
}
运行结果:
三月 12, 2017 2:22:44 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 14:22:44 GMT+08:00 2017]; root of context hierarchy
三月 12, 2017 2:22:44 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
com.spring.service.impl.UserServiceImpl的update方法被执行
修改用户
com.spring.service.impl.UserServiceImpl的add方法被执行
增加用户
故前置通知可以在spring当中被执行,接下可以完善通知;
方法执行后的----------------------------
public class AfterLog implements AfterReturningAdvice{
/**
* 目标方法执行后执行的通知
* returnValue--返回值
* method 被调用的方法对象
* args 被调用的方法对象的参数
* target 被调用的方法对象的目标对象
* */
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"被成功执行,返回值是:"+returnValue);
}
}
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class ExceptionLog implements ThrowsAdvice {
public void afterThrowing(Method method,Exception ex) throws Throwable {
}
}
重新配置:
<!-- 这个切面也要配置成bean-->
<bean id="log" class="com.spring.advice.Log"/>
<bean id="afterLog" class="com.spring.advice.AfterLog"></bean>
<aop:config>
<!--切入点,需要告诉方法在什么去执行
expression="execution(* com.spring.service.impl.*.*(..))"
第一个* 表示所有的返回值,然后就是包名
第二个*表示所有的类对象
第三个*表示类对象所有的方法
第四个*表示所有方法下面的带参数的方法或者是不带参数的方法
-->
<aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>
<!-- 在所有的方法中都切入前置通知-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
测试运行结果:
三月 12, 2017 2:28:19 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 14:28:19 GMT+08:00 2017]; root of context hierarchy
三月 12, 2017 2:28:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
com.spring.service.impl.UserServiceImpl的update方法被执行
修改用户
com.spring.service.impl.UserServiceImpl的update被成功执行,返回值是:null
com.spring.service.impl.UserServiceImpl的add方法被执行
增加用户
com.spring.service.impl.UserServiceImpl的add被成功执行,返回值是:null
总结:AOP的重要性,非常重要
Spring的AOP就是将公共的业务(如日志,安全等)和业务类结合。当执行业务的时候将会把公共业务加进来。实现公共业务的重复利用。我们自己的业务就会变得更加的纯粹,我们就可以关注我们的自己的业务,本质就是动态代理。
第二种方式:自定义类来实现AOP,不实现spring的自带的通知
第一步:重新通知:
public class Log {
public void before(){
System.out.println("方法执行前");
}
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="userService" class="com.spring.service.impl.UserServiceImpl"/>
<!-- 这个切面也要配置成bean-->
<bean id="log" class="com.spring.advice.Log"/>
<aop:config>
<!--切入点,需要告诉方法在什么去执行
expression="execution(* com.spring.service.impl.*.*(..))"
第一个* 表示所有的返回值,然后就是包名
第二个*表示所有的类对象
第三个*表示类对象所有的方法
第四个*表示所有方法下面的带参数的方法或者是不带参数的方法
-->
<aop:aspect ref="log">
<aop:pointcut expression="execution(* com.spring.service.impl.*.*(..))" id="pointcut"/>
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
第三种方式:通过注解实现AOP
第一步:修改log
package com.spring.advice;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.MethodBeforeAdvice;
@Aspect
public class Log {
@Before("execution(* com.spring.service.impl.*.*(..))")
public void before(){
System.out.println("方法执行前");
}
@After("execution(* com.spring.service.impl.*.*(..))")
public void after(){
System.out.println("方法执行后");
}
@Around("execution(* com.spring.service.impl.*.*(..))")
public Object around(ProceedingJoinPoint jp) throws Throwable{
System.out.println("环绕前");
System.out.println("方法"+jp.getSignature());
Object result=jp.proceed();
System.out.println("环绕后");
return result;
}
}
第二步:修改beans.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"
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="userService" class="com.spring.service.impl.UserServiceImpl"/>
<!-- 这个切面也要配置成bean-->
<bean id="log" class="com.spring.advice.Log"/>
<aop:aspectj-autoproxy/>
</beans>
第三步:运行:
三月 12, 2017 3:00:02 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@439f5b3d: startup date [Sun Mar 12 15:00:02 GMT+08:00 2017]; root of context hierarchy
三月 12, 2017 3:00:02 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
环绕前
方法void com.spring.service.UserService.update(int)
方法执行前
修改用户
环绕后
方法执行后
Spring_api方式实现aop的更多相关文章
- 使用Spring框架入门四:基于注解的方式的AOP的使用
一.简述 前面讲了基于XML配置的方式实现AOP,本文简单讲讲基于注解的方式实现. 基于注解的方式实现前,要先在xml配置中通过配置aop:aspectj-autoproxy来启用注解方式注入. &l ...
- 基于AspectJ的注解方式进行AOP开发
-------------------siwuxie095 基于 AspectJ 的注解方式进行 AOP 开发 ...
- 基于AspectJ的XML方式进行AOP开发
-------------------siwuxie095 基于 AspectJ 的 XML 方式进行 AOP 开发 1 ...
- spring----IOC注解方式以及AOP
技术分析之Spring框架的IOC功能之注解的方式 Spring框架的IOC之注解方式的快速入门 1. 步骤一:导入注解开发所有需要的jar包 * 引入IOC容器必须的6个jar包 * 多引入一个:S ...
- 特性attribute,声明和使用attribute,应用attribute,AOP面向切面,多种方式实现AOP
1 特性attribute,和注释有什么区别2 声明和使用attribute3 应用attribute4 AOP面向切面5 多种方式实现AOP ---------------------------- ...
- (转)使用Spring的注解方式实现AOP的细节
http://blog.csdn.net/yerenyuan_pku/article/details/52879669 前面我们已经入门使用Spring的注解方式实现AOP了,现在我们再来学习使用Sp ...
- (转)使用Spring的注解方式实现AOP入门
http://blog.csdn.net/yerenyuan_pku/article/details/52865330 首先在Eclipse中新建一个普通的Java Project,名称为spring ...
- 一起学Spring之注解和Schema方式实现AOP
概述 在上一篇,我们了解了通过实现接口和XML配置的方式来实现AOP,在实现注解方式AOP之前,先了解一下AspectJ.AspectJ是一个面向切面的框架,它扩展了Java语言,定义了AOP语法,能 ...
- 使用注解方式实现 AOP和IoC
使用注解方式实现AOP和IoC IOC和DI的注解 IOC: @Component:实现Bean组件的定义 @Repository:用于标注DAO类,功能与@Component作用相当 @Servic ...
随机推荐
- pvresize
lvm pv 扩容 pvresize 当PV对应的设备分区(如md软raid)扩容之后,利用该命令可以扩容PV
- 基于 react 的Java web 应用—— 组件复用(后续需更新)
前言 实习第二周,被告知要用React与导师进行基于React的Javaweb 的开发,jinzhangaaaaa~由于React 这款框架没学过,看了一峰老师的基础入门教程,硬着头皮开始上了... ...
- CSDN排名及积分规则
博客排行榜排名分值=个人Blog全部随笔与文章的阅读数之和+个人Blog全部评论数之和*10+个人所发表的评论数之和*50 CSDN博客积分计算规则: 1.每公布一篇原创或者翻译文章:可获得10分. ...
- [USACO1.3]虫洞wormhole
题目描述 农夫约翰爱好在周末进行高能物理实验的结果却适得其反,导致N个虫洞在农场上(2<=N<=12,n是偶数),每个在农场二维地图的一个不同点. 根据他的计算,约翰知道他的虫洞将形成 N ...
- 网络流 A - PIGS POJ - 1149 最大流
A - PIGS POJ - 1149 这个题目我开始感觉很难,然后去看了一份题解,写的很好 https://wenku.baidu.com/view/0ad00abec77da26925c5b01c ...
- SpringBoot:Demo
目录 Demo 准备工作 登录+拦截器 Restful CRUD Restful架构 查询所有员工 添加员工 员工修改功能 HiddenHttpMethodFilter 删除员工 定制错误页面 注销功 ...
- Day_10【常用API】扩展案例1_利用人出生日期到当前日期所经过的毫秒值计算出这个人活了多少天
分析以下需求,并用代码实现: 1.从键盘录入一个日期字符串,格式为 xxxx-xx-xx,代表该人的出生日期 2.利用人出生日期到当前日期所经过的毫秒值计算出这个人活了多少天 package com. ...
- VA01信贷使用
1业务场景 业务在正式机中发现,当使用VA01输入客户编号回车后会报错 2解决方法 1. SE24进入CL_IM_UKM_SD_FSCM_INTEGR1 2. 双击方法IF_EX_BADI_SD_CM ...
- Arrays.binarySearch的返回值
如果查找的值包含在数组中,返回搜索的第一个值的下标: 如果查找的值不在数组中,返回(-插入点-1):插入点即为第一个大于此查找值的元素下标 插入点 为将该值插入数组的那一点:即第一个大于此键的元素下标 ...
- [hdu5372 Segment Game]树状数组
题意:有两种操作:(1)插入线段,第i次插入的线段左边界为Li,长度为i (2)删除线段,删除第x次插入的线段.每次插入线段之前询问有多少条线段被它覆盖. 思路:由于插入的线段长度是递增的,所以第i次 ...