SpringAOP的简单实现
AOP,即面向切面编程,springAOP采用的是动态代理的技术
其主要作用可以做一些与业务逻辑无关,但却必须的操作,例如日志记录,权限管理,检查数据,等等。首先,来做一个小实现来方便理解
首先,建立一个maven工程,导入对于的包,我直接全部贴出来
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.lx</groupId>
<artifactId>springmvcdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>springmvcdemo</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<!-- spring的依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency> <!-- springMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency> <!-- Spring AOP模块 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.10.RELEASE</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency> </dependencies> <build> </build> </project>
加入MathCalculator 类,这个类就是我们的业务逻辑类,我们要对它进行切面编程
MathCalculator .java
public class MathCalculator { public int div(int i,int j) {
System.out.println("MathCalculator.div()被调用");
return i/j;
}
}
然后,建立一个切面类
/***
* 切面类
* @author hicku
*
*@Aspect:这个注解告诉spring,这个是一个切面类,而不是其他普通的类
*/ @Aspect
public class LogAspects { //抽取公共的切入点表达式
//1,本类引用
//2,其他的切面引用
//告诉他,这个是public的,返回参数类型是int,同时目标位置为MathCalculator下面的所有方法
@Pointcut("execution(public int com.lx.springmvcdemo.aop.MathCalculator.*(..))")
public void printCut() {} //@before,在目标方法之前切入,切入点表达式(指在哪个方法切入)
//@Before(value = "public int com.lx.springmvcdemo.aop.MathCalculator.*(..)")
//也可以用
@Before("printCut()")
public void logStart(JoinPoint joinPoint) {
Object[] obj=joinPoint.getArgs();
System.out.println("除法运行"+joinPoint.getSignature().getName()+"-------参数列表:"+Arrays.asList(obj));
} @After("execution(public int com.lx.springmvcdemo.aop.MathCalculator.*(..))")
public void logEnd(JoinPoint joinPoint) {
System.out.println("除法结束-------"+joinPoint.getSignature().getName());
} //JoinPoint这个参数一定要放在其他值的前面,否则会报错
@AfterReturning(value="printCut()",returning="result")
public void logReturn(JoinPoint joinPoint,Object result) {
System.out.println("除法返回正常-------运行结果("+result+")");
} @AfterThrowing(value="printCut()",throwing="exception")
public void logException(Exception exception) {
System.out.println("除法异常-------异常信息:{"+exception.toString()+"}");
}
}
如里面注释,需要@Aspect,让spring知道,这个是一个切面类
还有,注意,代码里面有两个切入代码表达式的方法。
然后,还要一个配置类,因为要用springAOP,你一定要用在spring里面注册了的bean,不然是用不了的
配置类如下:
@EnableAspectJAutoProxy
@Configuration
public class MainConfigofAOP { //业务逻辑类加入到容器中
@Bean
public MathCalculator mathCalculator() {
return new MathCalculator();
} //将切面类加入到容器中
@Bean
public LogAspects logAspects() {
return new LogAspects();
} }
最后,写一个测试类:
public class IOCTest_AOP { AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigofAOP.class); @Test
public void test01() {
//使用AOP一定要使用spring容器里面注册的bean来用,不能自己new一个MathCalculator,这样做是没有用的
//MathCalculator me=new MathCalculator();
//me.div(1, 1);
MathCalculator mathCalculator= (MathCalculator) applicationContext.getBean("mathCalculator");
mathCalculator.div(1, 0);
}
}
输出结果如下:
除法运行div-------参数列表:[1, 0]
MathCalculator.div()被调用
除法结束-------div
除法异常-------异常信息:{java.lang.ArithmeticException: / by zero}
最后,总结一下:
* AOP:【动态代理】
* 指,在程序运行期间,动态的将某一段代码切入制定的位置进行运行
*
* 1,导入AOP模块:spring AOP:(spring-aspects)pom.xml的包
* 2,定义一个业务逻辑类MathCaluculator():在业务逻辑的的时候将日志打印(方法之前,运行结束,出现异常)
* 3,定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCaluculator运行到哪里了
* 通知方法:
* 前置通知(@Before):logStart:在目标方法div运行之前运行
* 后置通知(@After):logEnd:在目标方法div运行结束之后运行
* 返回通知(@AfterReturning):logReturn:在目标正常返回之后运行
* 异常通知(@AfterThrowing):logException:在目标出现异常之后运行
* 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint。procced())
* 4,给切面类的目标方法标注何时何地运行(在LogAspects用通知注解)
* 5,将切面类和业务逻辑类(目标所在类)都加入到容器中
* 6,然后必须告诉spring,哪个是切面类(给切面类上加一个注解:@Aspect)
* 【7】,给配置文件中加入@EnableAspectJAutoProxy【开启基于注解的AOP模式】
* 在spring中有很多的@EnableXXXX,都是开启某一个功能的
* 其中JoinPrint这个参数一定要放到其他值的前面
* 三步:
* 1),将业务逻辑组件和切面类都加入到容器中,告诉spring哪个是切面类(@Aspect)
* 2),在切面类里面每一个通知方法上标注通知注解,告诉spring什么时候运行(切入点表达式:
* @Pointcut("execution(public int com.lx.springmvcdemo.aop.MathCalculator.*(..))"))或者是@Before什么的
* 3),上面第七步,开启注解AOP模式:@EnableAspectJAutoProxy
同IOC一样,这个AOP的原理也在看,
主要就是实现了这两个接口:implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
最后这就是后置处理器(后置处理器就是在bean初始化前后做的事情)和自动装配BeanFactory
SpringAOP的简单实现的更多相关文章
- spring-aop的简单实例注解版
项目结构如图,基本的spring的配置就不在赘述 1.首先编写自定义的切面类 package org.wu.test; import org.aspectj.lang.annotation.After ...
- AspectJ教学
这几天看JAVA基础看的有点头疼,决定时不时的换换口味,准备開始调研一些如今流行的技术,于是,開始埋头思考自己知识的盲区(当时,自己的知识盲区茫茫多...),想了几天后,决定要開始研究一下几种技术及实 ...
- SpringBoot CGLIB AOP解决Spring事务,对象调用自己方法事务失效.
对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,Sprin ...
- Spring详细教程
Spring学习总结---- 一.导入Spring必须的jar包 二.简单示例入门注入一个User 1.编写User实体类 package test.Spring.helloworld; import ...
- @Transactional spring 事务(转载)
原文链接: http://www.cnblogs.com/sweetchildomine/p/6978037.html?utm_source=itdadao&utm_medium=referr ...
- 理解SpingAOP
目录 什么是AOP? AOP术语 通知(Advice) 连接点(Join point) 切点(Pointcut) 连接点和切点的区别 切面(Aspect) 引入(Introduction) 织入(We ...
- SpringAOP+注解实现简单的日志管理
今天在再次深入学习SpringAOP之后想着基于注解的AOP实现日志功能,在面试过程中我们也经常会被问到:假如项目已经上线,如何增加一套日志功能?我们会说使用AOP,AOP也符合开闭原则:对代码的修改 ...
- spring-aop + memcached 的简单实现
一般情况下,java程序取一条数据是直接从数据库中去取,当数据库达到一定的连接数时,就会处于排队等待状态,某些在一定时间内不会发生变化的数据,完全没必要每次都从数据库中去取,使用spring-aop ...
- 基于Annotation与SpringAOP的缓存简单解决方案
前言: 由于项目的原因,需要对项目中大量访问多修改少的数据进行缓存并管理,为达到开发过程中通过Annotation简单的配置既可以完成对缓存的设置与更新的需求,故而设计的该简易的解决方案. 涉及技术: ...
随机推荐
- mybatis 基础详解
转 https://www.cnblogs.com/Mr-Kenson/p/8124680.html mybatis 是一个开源的 用于对数据库操作的框架, 读者基本都大体了解其基本功能, 我就不多解 ...
- python 面向对象一 OOP
一.面向对象和面相过程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面 ...
- 洛谷 P4009 汽车加油行驶问题 【最小费用最大流】
分层图,建k层,设(i,j,0)为点(i,j)的满油状态,全图的流量都是1,因为重复走到一个点没有意义.如果当前点是加油站,那么它向它上左的点连费用为a的边,向下右连费用为a+b的边: 否则,这个点的 ...
- Java键盘输入的方法
转载:http://blog.csdn.net/u012249177/article/details/49586383 java输入的方法: import java.io.BufferedReader ...
- 51nod 1186 质数检测 V2
1186 质数检测 V2 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 给出1个正整数N,检测N是否为质数.如果是,输出"Yes&quo ...
- Windows7运行无法记录历史命令问题解决
Windows7运行无法记录历史命令,每次都需要手动敲命令,解决方法如下: 1.任务栏中右键,选择"属性"菜单: 2.在弹出框中的"[开始]菜单"选项卡的隐私区 ...
- MyEclipse去除不必要的validation
MyEclipse在构建项目时去除不必要的Valication可以加快构建速度. 操作: Window->Perferences->MyEclipse->Validation 在Va ...
- 利用正则将xml数据解析为数组
function xml_to_array( $xml ) { $reg = '/<(\w+)[^>]*>([\x00-\xFF]*)<\/\1>/'; if(preg_ ...
- AJPFX总结IO流中的缓冲思想
缓冲思想 (因为内存的运算速度要远大于硬盘的原酸速度,所以只要降低硬盘的读写次数,就可以提高效率) 1. 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多, 2. 这是加 ...
- 老式浏览器支持html5和css3
在IE页面的head标签里面加入 <!-[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/ ...