spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)
1、Spring的AOP编程
什么是AOP? ----- 在软件行业AOP为Aspect Oriented Programming 也就是面向切面编程,使用AOP编程的好处就是:在不修改源代码的情况下,可以实现代码功能的增强
AOP的实现原理(掌握)
JDK的动态代理(注意JDK的动态代理只能对实现了接口的类产生代理)
/**
* Jdk的动态代理
* @author lilong
*/
public class JdkProxy implements InvocationHandler{
//要代理的对象
private CustomerDao customerDao;
public JdkProxy(CustomerDao customerDao){
this.customerDao = customerDao;
}
/**
* 生成代理对象的方法
* @return
*/
public CustomerDao createProxy(){
CustomerDao proxy = (CustomerDao) Proxy.newProxyInstance(customerDao.getClass().getClassLoader(), customerDao.getClass().getInterfaces(), this);
return proxy;
}
/**
* 增强的方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验...");
return method.invoke(customerDao, args);
}
}
编写测试代码:
@Test
public void test1(){
CustomerDao customerDao = new CustomerDaoImpl();
JdkProxy jdkProxy = new JdkProxy(customerDao);
CustomerDao proxy = jdkProxy.createProxy();
proxy.save();
}
第二种代理方式Cglib方式(了解或者欣赏)
注意的是:Cglib可以对没有实现接口的类产生代理,生成子类来实现功能的增强
public class CglibProxy implements MethodInterceptor{
//要代理的对象
private LinkManDao linkManDao;
public CglibProxy(LinkManDao linkManDao) {
this.linkManDao = linkManDao;
}
public LinkManDao createProxy(){
//创建Cglib核心类
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(linkManDao.getClass());
//设置回调
enhancer.setCallback(this);
//生成代理
LinkManDao proxy = (LinkManDao) enhancer.create();
return proxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("日志记录");
Object obj = methodProxy.invokeSuper(proxy, args);
return obj;
}
}
n 编写测试代码
@Test
public void test2(){
LinkManDao linkManDao = new LinkManDao();
CglibProxy cglibProxy = new CglibProxy(linkManDao);
LinkManDao proxy = cglibProxy.createProxy();
proxy.save();
}
2、Spring的AOP开发方式(xml方式)
其中相关术语的介绍

AOP开发所需要的jar介绍
n AOP联盟的jar包:com.springsource.org.aopalliance-1.0.0.jar
n Spring提供的AOP的jar包:spring-aop-4.2.4.RELEASE.jar
n AspectJ的jar包:com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
n Spring整合AspectJ的jar包:spring-aspects-4.2.4.RELEASE.jar

编写接口和实现类
ProductDao接口:
public interface ProductDao {
/**
* 持久层:产品保存
*/
public void save();
}
ProductDaoImpl实现类:
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("持久层:产品保存...");
}
}
配置相关类到Spring中
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="productDao" class="cn.itcast.dao.impl.ProductDaoImpl"></bean>
</beans>
编写切面类
/**
* 自定义切面类
* @author kevin
*/
public class MyAspectXml {
public void checkPrivilege(){
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="productDao" class="cn.itcast.dao.impl.ProductDaoImpl"></bean>
<bean id="myAspectXml" class="cn.itcast.aspect.MyAspectXml"></bean>
</beans>
进行AOP配置
<?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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="productDao" class="cn.itcast.dao.impl.ProductDaoImpl"></bean>
<bean id="myAspectXml" class="cn.itcast.aspect.MyAspectXml"></bean>
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>
编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestAOP {
@Autowired
private ProductDao productDao;
@Test
public void test1(){
productDao.save();
}
}
总结:对切入点表达式语法进行总结
语法:[修饰符] 返回类型 包名.类名.方法名(形式参数)
常见写法:
n execution(public * *(..)) 所有的public方法
n execution(* set(..)) 所有set开头的方法
n execution(* com.xyz.service.AccountService.*(..)) AccountService类中的所有方法
n execution(* com.xyz.service.*.*(..)) com.xyz.service包下所有的方法
n execution(* com.xyz.service..*.*(..)) com.xyz.service包及其子包下所有的方法
3、Spring中AOP的通知类型
1.1.1. 前置通知:在方法执行之前增强。可以获得切入点信息。
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<!-- 前置通知 -->
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
public class MyAspectXml {
public void checkPrivilege(JoinPoint point){
System.out.println("权限校验..." + point);
}
}
1.1.2. 后置通知:在方法执行完之后增强。可以获取返回值信息。
/**
* 自定义切面类
* @author kevin
*/
public class MyAspectXml {
public void checkPrivilege(JoinPoint point){
System.out.println("权限校验..." + point);
}
public void afterReturn(Object result){
System.out.println("后置通知:" + result);
}
}
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("持久层:产品保存...");
}
public int delete(){
System.out.println("持久层:产品删除...");
return 100;
}
}
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))" id="pointcut2"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<!-- 前置通知 -->
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
<!-- 后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut2" returning="result"/>
</aop:aspect>
</aop:config>
1.1.3. 环绕通知:在方法执行前后都进行增强。可以阻止方法的执行。
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("持久层:产品保存...");
}
public int delete(){
System.out.println("持久层:产品删除...");
return 100;
}
@Override
public void update() {
System.out.println("持久层:产品更新");
}
}
public class MyAspectXml {
public void checkPrivilege(JoinPoint point){
System.out.println("权限校验..." + point);
}
public void afterReturn(Object result){
System.out.println("后置通知:" + result);
}
public Object around(ProceedingJoinPoint joinpoint){
System.out.println("环绕前执行");
Object obj = null;
try {
obj = joinpoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("环绕后执行");
return obj;
}
}
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.update(..))" id="pointcut3"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<!-- 前置通知 -->
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
<!-- 后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut2" returning="result"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
</aop:aspect>
</aop:config>
1.1.4. 异常抛出通知:当发生异常之后增强,可以获取异常信息。
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("持久层:产品保存...");
}
public int delete(){
System.out.println("持久层:产品删除...");
return 100;
}
@Override
public void update() {
System.out.println("持久层:产品更新");
}
@Override
public void find() {
System.out.println("持久层:查询");
int i = 10/0;
}
}
public class MyAspectXml {
public void checkPrivilege(JoinPoint point){
System.out.println("权限校验..." + point);
}
public void afterReturn(Object result){
System.out.println("后置通知:" + result);
}
public Object around(ProceedingJoinPoint joinpoint){
System.out.println("环绕前执行");
Object obj = null;
try {
obj = joinpoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("环绕后执行");
return obj;
}
public void afterThrowing(Exception ex){
System.out.println("抛出异常通知:" + ex.getMessage());
}
}
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))" id="pointcut4"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<!-- 前置通知 -->
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
<!-- 后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut2" returning="result"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
<!-- 抛出异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
</aop:aspect>
</aop:config>
1.1.5. 最终通知:不管是否有异常,都会执行的
public class MyAspectXml {
public void checkPrivilege(JoinPoint point){
System.out.println("权限校验..." + point);
}
public void afterReturn(Object result){
System.out.println("后置通知:" + result);
}
public Object around(ProceedingJoinPoint joinpoint){
System.out.println("环绕前执行");
Object obj = null;
try {
obj = joinpoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("环绕后执行");
return obj;
}
public void afterThrowing(Exception ex){
System.out.println("抛出异常通知:" + ex.getMessage());
}
public void after(){
System.out.println("最终通知");
}
}
<!-- AOP配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.update(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))" id="pointcut4"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspectXml">
<!-- 前置通知 -->
<aop:before method="checkPrivilege" pointcut-ref="pointcut1"/>
<!-- 后置通知 -->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut2" returning="result"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3"/>
<!-- 抛出异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
注意:最终通知和后置通知的区别:最终通知,不管异常与否,都执行;而后置通知在异常时不执行。
4、Spring的AOP注解
4.1. 创建工程,引入jar包,创建核心配置文件

<?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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.itcast"></context:component-scan>
<!-- 开启自动代理注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
4.2. 创建接口和实现类
public interface ProductDao {
/**
* 持久层:产品保存
*/
public void save();
public int delete();
public void update();
public void find();
}
@Repository("productDao")
public class ProductDaoImpl implements ProductDao {
@Override
public void save() {
System.out.println("持久层:产品保存...");
}
public int delete(){
System.out.println("持久层:产品删除...");
return 100;
}
@Override
public void update() {
System.out.println("持久层:产品更新");
}
@Override
public void find() {
System.out.println("持久层:查询");
}
}
4.3. 编写切面类
@Component("myAspectAnnotation")
@Aspect
public class MyAspect {
@Before("execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))")
public void checkPrivilege(JoinPoint joinPoint){
System.out.println("权限校验..." + joinPoint.toString());
}
}
提示:此处的切面类可以不取id.
5、Spring的AOP 中注解通知
5.1. 前置通知
/**
* 前置通知
* @param joinPoint
*/
@Before("execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))")
public void checkPrivilege(JoinPoint joinPoint){
System.out.println("权限校验..." + joinPoint.toString());
}
5.2. 后置通知
@Aspect
public class MyAspect {
/**
* 前置通知
* @param joinPoint
*/
@Before("execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))")
public void checkPrivilege(JoinPoint joinPoint){
System.out.println("权限校验..." + joinPoint.toString());
}
@AfterReturning(value="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))",returning="result")
public void afterReturning(Object result){
System.out.println("后置通知:" + result);
}
}
5.3. 环绕通知
@Around("execution(* cn.itcast.dao.impl.ProductDaoImpl.update(..))")
public Object after(ProceedingJoinPoint joinpoint) throws Throwable{
System.out.println("环绕通知前增强");
Object obj = joinpoint.proceed();
System.out.println("环绕通知后增强");
return obj;
}
5.4. 异常通知
@AfterThrowing(value="execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))",throwing="ex")
public void afterThrowing(Exception ex){
System.out.println("抛出异常通知");
}
5.5. 最终通知
@After("execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))")
public void after(){
System.out.println("最终通知");
}
5.6. PointCut注解(了解)
作用:用于定义切入点表达式的一个注解。
@Component("myAspectAnnotation")
@Aspect
public class MyAspect {
/**
* 前置通知
* @param joinPoint
*/
@Before("execution(* cn.itcast.dao.impl.ProductDaoImpl.save(..))")
public void checkPrivilege(JoinPoint joinPoint){
System.out.println("权限校验..." + joinPoint.toString());
}
@AfterReturning(value="execution(* cn.itcast.dao.impl.ProductDaoImpl.delete(..))",returning="result")
public void afterReturning(Object result){
System.out.println("后置通知:" + result);
}
@Around("execution(* cn.itcast.dao.impl.ProductDaoImpl.update(..))")
public Object aroung(ProceedingJoinPoint joinpoint) throws Throwable{
System.out.println("环绕通知前增强");
Object obj = joinpoint.proceed();
System.out.println("环绕通知后增强");
return obj;
}
// @AfterThrowing(value="execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))",throwing="ex")
@AfterThrowing(value="MyAspect.pointcut()",throwing="ex")
public void afterThrowing(Exception ex){
System.out.println("抛出异常通知");
}
// @After("execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))")
@After("MyAspect.pointcut()")
public void after(){
System.out.println("最终通知");
}
@Pointcut("execution(* cn.itcast.dao.impl.ProductDaoImpl.find(..))")
public void pointcut(){
}
}
spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)的更多相关文章
- Spring官方文档翻译——15.1 介绍Spring Web MVC框架
Part V. The Web 文档的这一部分介绍了Spring框架对展现层的支持(尤其是基于web的展现层) Spring拥有自己的web框架--Spring Web MVC.在前两章中会有介绍. ...
- 是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了。
看了 Pivotal 公司的发展历史,这尼玛就是一场商业大片呀. 我们刚开始学习 Spring Boot 的时候肯定都会看到这么一句话: Spring Boot 是由 Pivotal 团队提供的全新框 ...
- 【转帖】是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了。
是时候给大家介绍 Spring Boot/Cloud 背后豪华的研发团队了. 2019/01/03 http://www.ityouknow.com/springboot/2019/01/03/spr ...
- Spring入门篇——第7章 Spring对AspectJ的支持
第7章 Spring对AspectJ的支持 介绍Spring对AspectJ的支持 7-1 AspectJ介绍及Pointcut注解应用 实例 完成了在xml文件的配置 7-2 Advice定义及实例 ...
- 带你手写基于 Spring 的可插拔式 RPC 框架(一)介绍
概述 首先这篇文章是要带大家来实现一个框架,听到框架大家可能会觉得非常高大上,其实这和我们平时写业务员代码没什么区别,但是框架是要给别人使用的,所以我们要换位思考,怎么才能让别人用着舒服,怎么样才能让 ...
- 关于如何介绍spring框架。
一.介绍Spring 1.Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架. 2.概念:轻量级的IOC(控制反转或者依赖注入).AOP(面向切面或者面向方面) ...
- Spring框架学习03——Spring Bean 的详解
1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...
- Spring4- 01 - Spring框架简介及官方压缩包目录介绍- Spring IoC 的概念 - Spring hello world环境搭建
一. Spring 框架简介及官方压缩包目录介绍 主要发明者:Rod Johnson 轮子理论推崇者: 2.1 轮子理论:不用重复发明轮子. 2.2 IT 行业:直接使用写好的代码. Spring 框 ...
- Spring框架IOC和AOP介绍
说明:本文部分内容参考其他优秀博客后结合自己实战例子改编如下 Spring框架是个轻量级的Java EE框架.所谓轻量级,是指不依赖于容器就能运行的.Struts.Hibernate也是轻量级的. 轻 ...
随机推荐
- Maven maven-compiler-plugin版本
项目执行Maven clean后出现WARNING提示.报如信息如下,根据报错信息 'build.plugins.plugin.version' for org.apache.maven.plugin ...
- 读取Execl表 导入数据库
不知不觉博客园园林都两年多了,我是今年毕业的应届生,最近公司项目需要改动,很多的数据需要导入,很多的实体类需要些.考虑到这些问题自己写了两个winform版的小工具,一个是读取Execl数据导入数据库 ...
- zabbix 问题汇总
1.Zabbix agent on Zabbix server is unreachable for 5 minutes 查看日志sudo tailf /var/log/zabbix/zabbix_a ...
- JAVA中String = null 与 String = "" 的区别
JAVA中String = null 与 String = ""的区别 笔者今天在Debug的时候发现的NPE(NullPointerException),辛辛苦苦地调试了半天,终 ...
- 201521123082 《Java程序设计》第13周学习总结
201521123082 <Java程序设计>第13周学习总结 标签(空格分隔): java 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. ...
- 第一周作业.四则运算生成器(基于python)
题目 从<构建之法>第一章的 "程序" 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 "软件",满足以下需求: 除了整数 ...
- 软件工程资料 - UCSD 怎么教软件工程
2012年,在上软件工程课的过程中,收集到这个博客,作为学习资料. 原网站 (http://www.arc-trooper.com)已经不存在,这是一个备份. ----------------- 以下 ...
- 201521123061 《Java程序设计》第六周学习总结
201521123061 <Java程序设计>第六周学习总结 ***代码阅读:Child压缩包内 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核 ...
- 201521123001《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 答:关于接口: 1.接口是一种抽象,抽取出了共同行为: 2.能够更加清晰地把系统 ...
- 201521123047 j第五周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 参考资料: 百度脑图 XMind 2. 书面作业 1.代码阅读:Child压缩包 ...