Spring_Aop的xml和注解的使用
动态代理:
目的:在不改变源代码的情况下,对方法进行增强!
动态代理又分为两种:
1.第一个就是基于接口的动态代理,他是由jdk提供的
2.基于子类的动态代理:cglib提供的:要想使用基于子类的动态代理:就必须得导入cglib的jar包
特性:被代理对象的任意方法
Spring_aop:总结
aop(Aspect Oriented Programming) :面向切面编程
切面:相对于业务主线的额外的功能模块
在不改变程序源代码的情况下对方法进行增强
aop的底层原理就是动态代理
aop的底层他会自动的根据代码,选择是使用基于还是使用子类的动态代理!
使用aop进行编程有啥好处呢?
1.简化业务代码
2.维护简单
Aop相关术语
Joinpoint(连接点):执行的方法
pointcut(切入点):被增强的方法
Advice(通知/增强):就是额外的功能模块
前置通知
后置通知
异常通知
最终通知
环绕通知
Aspect(切面):
对那个方法进行怎样的增强
学习Aop重点关注的事情是啥呢?
1.重点关注的是一个一个的额外的功能模块
2.aop的配置
第三 spring Aop的开发流程
定义一个切面类
普通的Java类,在这个类中通过一个一个的方法对目标对象进行增强
2.配置Aop
在xml里面配置文件中aop
i.将切面类交给spring管理
ii.声明Aop配置
<aop:config>
iii.定义切入点
aop:pointcut
iiii.定义通知类型
<aop:aspect ref = "切面类的引用">
前置通知
<aop:before method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
后置通知<aop:afterRunturning method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
异常通知<aop:after-throwing method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
最终通知<aop:after method="切面类的方法名" pointcut-ref="切入点表达式是引用"/>
注意:异常通知只有出现了异常了 才会有通知
</aop:aspect>
基于注解的Aop配置(结合xml)
1.将切面类交给spring管理
2.使用注解的形式代替xml中的aop的配置
3.使用注解配置spring的ioc或者aop的时候都需要开启对注解的支持!
注意:使用注解配置Aop和xml配置Aop在后置通知的时候,有一些差别!
注解的配置:是最后执行后置通知!
纯注解配置Aop
1.声明配置类
2.开启对ioc的支持
3.开启对aop注解的支持
@EnableAspectJAutoProxy
开发步骤以及代码的解释
<!-- 将切面类交给spring管理 -->
<bean id="logger" class="cn.itcast.utils.Logger"></bean>
<!-- 声明AOP配置:需要使用aop的命名空间(必须导入aop的约束)
aop:config : 声明aop配置
-->
<aop:config>
<!-- 定义切入点:定义被增强的方法
expression : execution(类的修饰符 返回值 包名.包名...类名.方法名(参数列表))
1.类的修饰符可以省略 :返回值 包名.包名...类名.方法名(参数列表)
2.返回值可以使用*号代替:标识任意返回值都可以
3.包名可以使用*号代替,一个包需要一个*
4.包名..代表此包 以及 此包的任意子包
5.类名可以使用*代替,代表任意类
6.方法名可以使用*代理,代表任意方法
7.参数类别可以使用..代表任意参数
**** 此写法 * *..*.*(..) 不推荐
-->
<aop:pointcut expression="execution(* cn.itcast.service.impl..*.*(..))" id="pt"/>
<!-- 配置切面
aop:aspect
ref:被spring管理的切面类的引用
-->
<aop:aspect ref="logger">
<!-- 定义通知的类型
aop:before 定义前置通知
method:切面类中定义的方法名
pointcut-ref:切入点表达式是引用
-->
<aop:before method="before" pointcut-ref="pt"/>
这是xml里面的配置
注解配合xml使用代码以及解释
<!-- 开启对spring ioc的支持 -->
<context:component-scan base-package="cn.itcast"></context:component-scan>
<!-- 开启对aop注解的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
/*
* 切面类:
* 对目标对象进行日志部分的增强是通过此类中的方法来实现
* 在切面类上
* 定义切面类
* 在切面方法上
* 使用注解的形式定义通知类型
*/
@Component("logger")
@Aspect
public class Logger {//这是配置到类上的
/**
* 抽取切入点表达式
* @Pointcut:定义切入点表达式
* 这个注解需要配置到方法上,这个方法是一个空的方法
* 应用这个切入点表达式的时候,只需要引入方法名就可以了
* 但是需要 方法名() 需要加括号
*/
@Pointcut(value="execution(* cn.itcast.service.impl..*.*(..))")//注意:类名前面那两个点改成一个点也是可以的
@Pointcut(value="execution(* cn.itcast.service.impl.*.add*(..))")//这是指定对那个方法进行增强
public void pt() {//定义一个通用的,这样前置通知,后置通知等等用的时候只需要引用这个方法名就行了
}
/**
* 定义前置通知
* @Before :
* value : 可以是一个切入点表达式,也可以是一个切入点表达式的引用
* 切入点表达式
*/
@Before("pt()")
public void before() {
System.out.println("进入方法之前打印日志");
}
*这是注解配置xml的方法
纯注解的配置方式
/*
* 切面类:
* 对目标对象进行日志部分的增强是通过此类中的方法来实现
* 在切面类上
* 定义切面类
* 在切面方法上
* 使用注解的形式定义通知类型
*/
@Component("logger")
@Aspect
public class Logger {
/**
* 抽取切入点表达式
* @Pointcut:定义切入点表达式
* 这个注解需要配置到方法上,这个方法是一个空的方法
* 应用这个切入点表达式的时候,只需要引入方法名就可以了
* 但是需要 方法名() 需要加括号
*/
@Pointcut(value="execution(* cn.itcast.service.impl..*.*(..))")
public void pt() {
}
/**
* 定义前置通知
* @Before :
* value : 可以是一个切入点表达式,也可以是一个切入点表达式的引用
* 切入点表达式
*/
@Before("pt()")
public void before() {
System.out.println("进入方法之前打印日志");
}
@AfterReturning("pt()")
public void afterReturning() {
System.out.println("执行目标方法得到返回值后打印日志");
}
@AfterThrowing("pt()")
public void afterThrowing() {
System.out.println("抛出异常打印日志");
}
@After("pt()")
public void after() {
System.out.println("在最终代码块中打印日志");
}
//5.定义环绕通知
/**
* 环绕通知是spring提供的一种
* 让程序员手动指定要执行的增强方法的一种手段,
* 在此方法中可以根据需求自定义以上4中通知类型
* 在环绕通知中,需要手动去调用被增强的方法
* 借助spring提供的一个对象ProceedingJoinPoint
* 此对象中有一个方法,可以调用被增强的方法
* pjp.proceed();执行被增强的的方法
* eg:动态代理中的,method.invoke();
*
* @throws Throwable
*/
@Around("execution(* cn.itcast.service.impl..*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("前置通知");
Object obj = null;
try{
obj = pjp.proceed();
System.out.println("后置通知");
}catch(Exception e){
System.out.println("异常通知");
e.printStackTrace();
}finally{
System.out.println("最终通知");
}
return obj;
}
}
/spring的配置类
//在配置类中替换xml配置文件中的剩余配置项
/**
* 1。声明配置类
* 2。开启对ioc的支持
* 3。开启对AOP注解的支持
* @EnableAspectJAutoProxy
*
*/
@Configuration
@ComponentScan(basePackages="cn.itcast")
@EnableAspectJAutoProxy
public class Config {
}
public class Client {
public static void main(String[] args) {
//测试ioc的配置
//ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
CustomerService customerService = (CustomerService)ac.getBean("customerService");
customerService.updateCustomer();
}
}
这是纯注解的方式
Aop事物案例
@Component("logger")
@Aspect
public class Logger {
@Pointcut(value="execution(* cn.crm.service.impl..*.*(..))")
public void pt(){
}
@Around(value="pt()")
public Object tx(ProceedingJoinPoint pjp) throws Throwable{
Session session = null;
Transaction tx = null;
Object obj = null;
try {
session = HibernateUtils.getCurrentSession();
tx = session.beginTransaction();
obj = pjp.proceed();
tx.commit();
} catch (Exception e) {
System.out.println("出现异常了");
tx.rollback();
}finally {
System.out.println("最终执行的代码");
}
return obj;
}
}
public class Client{
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
CustomerService customerService = (CustomerService)ac.getBean("customerService");
Customer customer = new Customer();
customer.setCustName("hello");
customerService.addCustomer(customer);
}
}
xml配置:
<context:component-scan base-package="cn.crm"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
这是一个小小的Aop的事物案例,当然Spring也提供了事物的支持,但是今天只做了个Aop的事物,希望对大家有帮助
Spring_Aop的xml和注解的使用的更多相关文章
- 关于Mybatis中Mapper是使用XML还是注解的一些思考
XML 据说可以灵活的进行注解,但是修改以后还是要重新发布程序.当然,你可以说,在Tomcat中改了,然后热加载了,不就可以了.可是一般情况下都是几台,十几台服务器.都是用发布系统,持续集成的方式部署 ...
- 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比
[原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...
- 1-spring xml 和 注解 解析过程
spring mvc 入口 DispatcherServlet,类关系图如下所示 DispatcherServlet 就是一个 Servlet,那Servlet 的初始化方法 init()在哪里,通过 ...
- MyBatis 使用简单的 XML或注解用于配置和原始映射
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .My ...
- Mybatis之XML、注解
前言 上篇简单介绍了Mybatis的简单实用,本篇先对上次实验环境的一些内容进行优化,然后验证Mybatis的XML配置以及注解方式. 实验环境优化 数据库配置 在mybatis的配置文件中,引入数据 ...
- 使用spring框架时,使用xml还是注解
1 xml的优缺点 1.1 优点 解耦合,方便维护.xml不入侵代码,方便代码阅读. 1.2 缺点 开发速度慢. 2 注解的优缺点 2.1 优点 能够加快开发速度,因为它将常用的主体逻辑隐藏在注解中了 ...
- day38 18-Spring的XML和注解的结合使用
什么情况下使用XML,什么情况下使用注解?又有XML,又有注解,开发的时候使用哪种? XML:结构清晰,配置麻烦. 注解:简单, 它俩的结合点在属性注入上. 两种方式结合:一般使用XML注册Bean, ...
- 八 Spring的IOC的XML和注解的区别及其整合开发
xml和注解的区别 xml和注解整合开发 注解:取消扫描配置开启注解配置 扫描:<context:component-scan base-package="" /> ...
- 二十 Spring的事务管理及其API&事务的传播行为,编程式&声明式(xml式&注解式,底层AOP),转账案例
Spring提供两种事务方式:编程式和声明式(重点) 前者需要手写代码,后者通过配置实现. 事务的回顾: 事务:逻辑上的一组操作,组成这组事务的各个单元,要么全部成功,要么全部失败 事务的特性:ACI ...
随机推荐
- 智能合约语言Solidity教程系列2 - 地址类型介绍
智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...
- [置顶]
spring集成mina 实现消息推送以及转发
spring集成mina: 在学习mina这块时,在网上找了很多资料,只有一些demo,只能实现客户端向服务端发送消息.建立长连接之类.但是实际上在项目中,并不简单实现这些,还有业务逻辑之类的处理以及 ...
- 图片布局css
对于平时项目开发中,经常要展示图片.什么水平居中显示,垂直居中显示,水平或垂直居中显示...我们的发际线就是这样往后退的. 接下来要讲的就是对于各种图片布局的css实现(这里针对的是img标签的不会使 ...
- Solr管理界面详解
- Django1.10+Mysql 5.7存储emoji表情,报Incorrect string value: '\\xF0\\x9F\\x90\\xA8' for column 'signature' at row 1的解决方法
问题: 在做webapp项目的时候,用户提交emoji数据,控制台报错:Incorrect string value: '\\xF0\\x9F\\x90\\xA8' for column 'signa ...
- 本地创建Duplicate数据库
本地创建Duplicate数据库,新创建的文件路径与目标数据库不同,并且辅助实例的初始化參数DB_NAME与目标数据库不能同样. 1.创建辅助实例的秘钥文件 [oracle@linux5 dbs]$ ...
- Android PopupWindows
今天了解到PopupWindows这个布局,PopupWindow这个类用来实现一个弹出框,能够使用随意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的. 以下是一个实例 xml ...
- Javascript--cookie创建与查看
创建cookie 以下代码将创建一个cookie,该cookie名称为UserName,值为Paul,过期时间为7天后(2015年6月29日) <span style="font-si ...
- jquery 自定义选择器
// HTML 代码 <body> <div id="divid1" class="divclass">白色</div> & ...
- java语言实现树
首先用Node类定义一个节点,用来存储每个节点的内容: public class Node { // 关键字 private int keyData; // 其他数据 private int othe ...