顾问包装通知

通知(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. java8 : 流

    package day02.com.offcn.test; import java.io.IOException; import java.nio.charset.Charset; import ja ...

  2. 03 python 对象笔记

    类的命名方法 1.使用大驼峰命名法:每一个单词的首字母大写(第一个的也要)2.单词之间不需要下划线 对象的内置函数和属性 1.使用dir()函数来获取对象的内置方法和属性.返回值是一个列表.2.返回中 ...

  3. TCP,SYN,FIN扫描

    1.TCP扫描相对来说是速度比较慢的一种,为什么会慢呢?因为这种方法在扫描的时候会从本地主机的一个端口向目标主机的一个端口发出一个连接请求报文段,而目标主机在收到这个这个请求报文后: 有回复: 若同意 ...

  4. 使用MD5加密字符串

    一.概念: MD5码以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值. 二 ...

  5. 在Linux上安装Zookeeper集群

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.——这才是真正的堪称强大!! - ...

  6. element-ui 省市区联动组件 el-cascader

    <el-form-item label="省市 :" prop="description"> <el-cascader size=" ...

  7. lumen中安装及使用redis作为cache

      1.安装redis模块在compose.json的require中添加 "predis/predis": "*","illuminate/redi ...

  8. CentOS7安装CDH 第十三章:CDH资源池配置

    相关文章链接 CentOS7安装CDH 第一章:CentOS7系统安装 CentOS7安装CDH 第二章:CentOS7各个软件安装和启动 CentOS7安装CDH 第三章:CDH中的问题和解决方法 ...

  9. 【DRF框架】路由组件

    视图组件涉及的路由补充: from rest_framework.viewsets import ViewSetMixin 对路由进行了重新的分发,重写了as_view() 方法,重新封装了请求方法 ...

  10. Django中过滤的实现

    过滤模块 安装 >: pip install django-filter 注册应用:settings/dev.py INSTALLED_APPS = [ # 列表过滤模块 'django_fil ...