顾问包装通知

通知(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. Java字符串定义及常用方法

    String.StringBuffer和StringBuilder   String修饰的是不可变的字符串,而StringBuffer和StringBuilder类的对象是可以被修改的.   Stri ...

  2. C++打印杨辉三角形

    #include <iostream> #include <iomanip> #include <Windows.h> using namespace std; # ...

  3. Python——成员变量

    一.类变量 在类命名空间内定义的变量就属于类变量,python允许使用类来修改.读取类变量. 例: class a: b = '我是类变量' def c(self): print (a.b) # 通过 ...

  4. Python字符串图解

    >>> word = "Python" >>> word[:2]  # character from the beginning to posi ...

  5. Java中final与C++中const的关系

    Java中的final有三种主要用法: (1)修饰变量: final变量是不可改变的,但它的值可以在运行时刻初始化,也可以在编译时刻初始化,甚至可以放在构造函数中初始化,而不必在声明的时候初始化,所以 ...

  6. vue 下拉刷新数据的插件的使用:

    1.安装: npm i vue-scroller -S npm install vue-scroller -D 2.在需要加载的页面中引入,或在公共js文件中引入: import VueScrolle ...

  7. echarts饼状图位置设置

    series: { name: "流量占比分布", type: "pie", radius: ["40%", "60%" ...

  8. react 提示消息队列 (支持动态添加,删除,多实例化)

    import React from 'react' import PropTypes from 'prop-types' import AnimationOperateFeedbackInfo fro ...

  9. 怎么将visual studio项目打包生成dll文件

    1.打开电脑再打开visual studio软件,在软件里面新建一个项目,文件---->新建---->项目,打开新建项目窗口. 2.选择C#类工程,并为项目命名. 3.将类库文件class ...

  10. pdm文件打开方式

    转自:https://blog.csdn.net/qq_36855191/article/details/79299216 pdm打开网站:http://www.dmanywhere.cn/