顾问包装通知

通知(advice)是Spring中的一种比较简单的切面,只能将切面织入到目标类的所有方法中,而无法对指定方法进行增强 顾问(advisor)是Spring提供的另外一种切面,可以织入到指定的方法中  接口 PointcutAdvisor

实现类:NameMatchMethodPointcutAdvisor(基于方法名称的增强顾问),RegexpMethodPointcutAdvice(基于正则表达式的增强顾问)

新增advisor包,实现顾问的测试用例

新建app-02.xml文件,内容如下

<!--将目标对象声明到Spring容器中-->
<bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean> <!--将advice声明到容器中-->
<bean id="advice" class="com.cmy.CodeAdvice.BeforeAndAfter"></bean> <!--配置顾问:包装通知-->
<bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="advice"></property>
<!--指定为say方法实现增强-->
<property name="mappedName" value="say"></property>
</bean> <!--配置代理工厂-->
<bean id="proxyfactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="doSomeService"></property>
<!--将通知替换成为顾问-->
<property name="interceptorNames" value="advisor"></property>
</bean>

以上文件使用的是NameMatchMethodPointcutAdvisor,当然也可替换成为 RegExpMethodPonitcutAdvisor,基于正则表达式通配方法名的顾问,可配置性更加优良。

<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice"></property>
<!--指定为带say的函数进行增强-->
<property name="pattern" value=".*say.*"></property>
</bean>

顾问代理生成器

顾问代理生成器,当我们声明好顾问后为目标对象生成代理对象。如果项目中 存在多个代理对象的话,需要实例化许多的ProxyFactoryBean,我们可以使用顾 问 代理生成器来解决这个问题。

顾问代理生成器主要分两种

      自动顾问代理生成器:DefaultAdvisorAutoProxyCreator

      名称顾问代理生成器:BeanNameAutoProxyCreator

  继续使用advisor包,创建app-03.xml文件,新增顾问代理生成器

--将目标对象声明到Spring容器中-->
<bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
<!--将advice声明到容器中-->
<bean id="advice" class="com.cmy.CodeAdvice.BeforeAndAfter"></bean>
<!--顾问包装通知-->
<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice"></property>
<!--指定为带say的函数进行增强-->
<property name="pattern" value=".*say.*"></property>
</bean> <!--名称顾问代理生成器:需要指定被代理的目标对象和顾问名-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="doSomeService"></property>
<property name="interceptorNames" value="advisor"></property>
</bean>

创建测试用例

public class Demo2 {
public static void main(String[] args) {
//声明式增强 必须加载Spring容器
ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/advisor/app-03.xml");
//在Spring容器中已直接为DoSomeService创建好了代理对象 无需创建代理工厂
DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
doSomeService.say();
}
}

IOC和DI的注解

IOC:

@Component:实现Bean组件的定义

@Repository:用于标注DAO类,功能与@Component作用相当

@Service:用于标注业务类

@Controller:用于标注控制器

DI:

@Resource(name="userService")

默认ByName方式,如果name确实默认按照ByType方式注入

@Autowired

默认ByType方式,如果出现同名类,则不能按照Type进行注入

需要使用@Qualifier 指明ID

使用注解方式实现Spring AOP

实现AOP的注解有

@Aspect 声明切面

@Ponitcut 声明公共的切点表达式

@Before 前置增强

@AfterReturning 后置增强

@Around 环绕增强

@AfterThrowing 异常抛出增强

@After 最终增强

使用注解实现前置+后置增强

/**
* 使用注解定义切面
*/
@Aspect
public class UserServiceLogger {
@Pointcut("execution(* com.cmy.service.*.*(..))")
public void pointcut() {} @Before("pointcut()")
public void before(JoinPoint jp) {
System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
@AfterReturning(pointcut = "pointcut()", returning = "returnValue")
public void afterReturning(JoinPoint jp, Object returnValue) {
System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法返回值:" + returnValue);
}
}

创建Spring的核心配置文件,开启Spring对IOC和AOP注解的支持

新增app-07.xml文件

<!--开启Spring IOC的注解支持 base-package 包扫描语句 com.cmy包下的注解-->
<context:component-scan base-package="com.cmy"/>
<!--配置增强类 交给Spring容器管理-->
<bean class="com.cmy.AfterAndBefore.UserServiceLogger"></bean>
<!--开启Spring AOP注解的支持-->
<aop:aspectj-autoproxy />

在service包下给DoSomeServiceImpl声明@Service注解

Service("doSomeService")//与<bean id="doSomeService" class="XXX">相同
public class DoSomeServiceImpl implements DoSomeService { @Override
public void say() {
//int result=5/0;
System.out.println("呵呵");
}
}

测试类

public class Demo {
public static void main(String[] args) {
//声明式增强 必须加载Spring容器
ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/AfterAndBefore/app-07.xml");
//获取代理对象
DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
doSomeService.say();
}
}

Spring第四天的更多相关文章

  1. Spring系列(四) 面向切面的Spring

    除了IOC外, AOP是Spring的另一个核心. Spring利用AOP解决应用横切关注点(cross-cutting concern)与业务逻辑的分离, 目的是解耦合. 横切关注点是指散布于代码多 ...

  2. Spring Boot(四) Mybatis-MySql

    Spring Boot(四) Mybatis-MySql 0.准备数据库表 -- ---------------------------- -- Table structure for person ...

  3. 阶段3 2.Spring_01.Spring框架简介_01.spring课程四天安排

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  4. spring security四种实现方式

    spring security四种实现方式 spring(20) > 目录(?)[+] 最简单配置spring-securityxml实现1 实现UserDetailsService 实现动态过 ...

  5. 学习spring第四天

    Spring第四天讲义 今日内容 Spring的事务管理 Spring和MyBatis框架的集成 1. Spring的事务管理 1.1. 事务是什么? 在操作数据库时(增删改),如果同时操作多次数据, ...

  6. Spring第四天,BeanPostProcessor源码分析,彻底搞懂IOC注入及注解优先级问题!

  7. spring boot(四):thymeleaf使用详解

    在上篇文章springboot(二):web综合开发中简单介绍了一下thymeleaf,这篇文章将更加全面详细的介绍thymeleaf的使用.thymeleaf 是新一代的模板引擎,在spring4. ...

  8. Spring笔记(四)SpingAOP

    需要的Jar包(String3.2) com.springsource.net.sf.cglib-2.2.0.jar // 作用于cglib方式的动态代理 com.springsource.org.a ...

  9. Spring(四)-- JdbcTemplate、声明式事务

    1.Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装.语法风格非常接近DBUtils.   JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcT ...

  10. Java框架之Spring(四)

    本文主要讲述在Spring中 1 注解方式装配 2 以自动扫描把组件纳入spring容器中管理 3 面象切面编程-代理的jdk 版实现 4 使用 Cglib 生成代理 5 aop编程的一些概念 6 使 ...

随机推荐

  1. 2019ICPC南昌现场赛总结

    非常可惜的一场比赛,多了60分钟罚时与银牌无缘.今年6场ICPC网络赛里面打的最差的就是南昌站,冥冥之中自有天意吧,最后被安排去了南昌. 开场被队友叫去先看的L,说是足球,发现就是简单模拟,就直接上机 ...

  2. 2019最新黑链代码expression:隐藏链接代码

    之前有收集了一些主流的隐藏链接代码,最近又发现一种相当牛X的代码,如下: 源代码: <div style="position:absolute;left:expression(1-90 ...

  3. 第四章 函数之lambda 表达式和内置函数

    4.5 lambda 表达式 用于表示简单的函数. # 三元运算,为了解决简单的if else的情况,如:if 1 == 1:    a = 123else:    a = 456# 相当于a = 1 ...

  4. 解决VS2017中使用scanf函数报错的问题

    我们在VS2017中如果使用C语言的scanf输入函数,编译的时候编译器会报error C4996: 'scanf': This function or variable may be unsafe. ...

  5. python实战项目 — 爬取中国票房网年度电影信息并保存在csv

    import pandas as pd import requests from bs4 import BeautifulSoup import time def spider(url, header ...

  6. PAT(B) 1087 有多少不同的值(Java)规律

    题目链接:1087 有多少不同的值 (20 point(s)) 题目描述 当自然数 n 依次取 1.2.3.--.N 时,算式 ⌊n/2⌋+⌊n/3⌋+⌊n/5⌋ 有多少个不同的值?(注:⌊x⌋ 为取 ...

  7. PAT(B) 1031 查验身份证(Java)

    题目链接:1031 查验身份证 (15 point(s)) 题目描述 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配 ...

  8. BZOJ4400 TJOI2012桥(最短路+线段树)

    首先找出任意一条1-n的最短路径.显然删除的边只有在该最短路上才会对最短路长度产生影响. 不会证明地给出一个找不到反例的结论:删除一条边后,新图中一定有一条1-n的最短路径上存在一条边x->y, ...

  9. shell 学习笔记8-case条件语句

    一.case语句简介 1.什么是case条件语句 case条件语句就相当于多分支的if/elif/else条件语句,但是比这样的语句更规范更好看,经常被用在失效系统服务启动脚本等企业应用中 程序将ca ...

  10. js 遍历树的层级关系的实现

    1.遍历树的层级关系 1)先整理数据 2)找到id和数据的映射关系 3)然后找到父节点的数据,进行存储 test() { const list = [ { id: ", parentId: ...