1.面向切面编程

  在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程叫做面向切面编程

2.常用概念

  原有功能:切点,pointcut

  前置通知:在切点之前执行的功能,before advice

  后置通知:在切点之后执行的功能,after advice

  如果切点执行过程中出现异常,会触发异常通知,throws advice

  所有功能的总称叫做切面

  织入:把切面嵌入原有功能的过程叫做织入

3.Schema-based方式

  每个通知都需要实现接口或类

  配置spring配置文件时在<aop:config>配置

4.AspectJ方式

  每个通知不需要实现接口或类

  配置spring配置文件时在<aop:config>的子标签<aop:aspect>中配置

5.Schema-based

Demo.java

public class Demo {
public void demo1(){
System.out.println("demo1");
}
public void demo2(){
System.out.println("demo2");
}
public void demo3(){
System.out.println("demo3");
}
}

  (1)导入jar包

    aopalliance-1.0.jar

    aspectjweaver-1.9.2.jar

  (2)新建前置通知类

  arg0:切点方法对象Method对象

  arg1:切点方法参数

  arg2:切点方法所在类的对象

public class MyBeforeAdvice implements MethodBeforeAdvice{

    @Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("执行前置通知");
}
}

  (3)新建后置通知类

  arg0:切点方法返回值

  arg1:切点方法对象Method对象

  arg2:切点方法参数

  arg3:切点方法所在类的对象

public class MyAfterAdvice implements AfterReturningAdvice {

    @Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("执行后置通知");
}
}

  (4)配置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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置通知类的对象,在切面中引入 -->
<bean id="mybefore" class="com.mxj.advice.MyBeforeAdvice"></bean>
<bean id="myafter" class="com.mxj.advice.MyAfterAdvice"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 *通配符:匹配任意方法名,任意类名,任意一级包名;(..):任意类型参数-->
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo2())" id="mypoint"/>
<!-- 通知 -->
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/>
</aop:config>
<!-- 配置Demo类 -->
<bean id="demo" class="com.mxj.test.Demo"></bean>
</beans>

6.配置异常通知的步骤(AspectJ方式)

  (1)只有切点报异常才能触发异常通知

  (2)在spring中只有AspectJ方式提供了异常通知的方法

  (3)实现步骤

新建类,在类中写任意名称的方法

public class MyThrowAdvice {
public void myexception(){
System.out.println("执行异常通知");
}
}

在spring配置文件中配置

  <aop:aspect>的ref属性表示:方法在哪个类中

  <aop:xxxx/>表示xxx通知

  method:当触发这个通知时调用哪个方法

  throwing:异常对象名,必须和通知中方法参数名相同(可以不在通知中声明异常对象)

  <bean id="mythrow" class="com.mxj.advice.MyThrowAdvice"></bean>
<aop:config>
<aop:aspect ref="mythrow">
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/>
<aop:after-throwing method="myexception()" pointcut-ref="mypoint" throwing="e"/>
</aop:aspect>
</aop:config>
<bean id="demo" class="com.mxj.test.Demo"></bean>

7.异常通知(Schema-based方式)

  (1)新建一个类实现throwsAdvice接口

public class MyThrow implements ThrowsAdvice{
public void afterThrowing(Exception ex) throws Throwable {
System.out.println("执行异常通知:schema-base方式");
}
}

  (2)配置applicationContext.xml

 <bean id="mythrow" class="com.mxj.advice.MyThrow"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/>
</aop:config>
<bean id="demo" class="com.mxj.test.Demo"></bean>

8.环绕通知(Schema-based方式)

  把前置通知和后置通知都写到一个通知中,就组成了环绕通知

  (1)新建一个类实现 MethodInterceptor(拦截器)

public class MyArround implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("环绕-前置");
Object result = arg0.proceed();
System.out.println("环绕-后置");
return result;
}
}

  (2)配置applicationContext.xml

<?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"
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">
<!-- 异常通知 -->
<!-- <bean id="mythrow" class="com.mxj.advice.MyThrow"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/>
</aop:config>
<bean id="demo" class="com.mxj.test.Demo"></bean> --> <bean id="myarround" class="com.mxj.advice.MyArround"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/>
<aop:advisor advice-ref="myarround" pointcut-ref="mypoint"/>
</aop:config>
<bean id="demo" class="com.mxj.test.Demo"></bean>
</beans>

9.AspectJ方式实现

类中方法名任意

public class MyAdvice {
public void mybefore(){
System.out.println("前置");
}
public void myafter(){
System.out.println("后置1");
}
public void myaftering(){
System.out.println("后置2");
}
public void mythrow(){
System.out.println("异常");
}
public Object myarround(ProceedingJoinPoint p) throws Throwable{
System.out.println("执行环绕");
System.out.println("环绕-前置");
Object result = p.proceed();
System.out.println("环绕-后置");
return result;
}
}

配置spring配置文件

  <aop:after/> 后置通知,是否出现异常都执行

  <aop:after-returning/> 后置通知,只有当切点正确执行时执行

  <aop:after/>、<aop:after-returning/>、<aop:after-throwing/>执行顺序和配置顺序有关

<?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"
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">
<bean id="demo" class="com.mxj.test.Demo"></bean>
<bean id="myadvice" class="com.mxj.advice.MyAdvice"></bean>
<aop:config>
<aop:aspect ref="myadvice">
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1())" id="mypoint"/>
<aop:before method="mybefore" pointcut-ref="mypoint"/>
<aop:after method="myafter" pointcut-ref="mypoint"/>
<aop:after-returning method="myaftering" pointcut-ref="mypoint"/>
<aop:after-throwing method="mythrow" pointcut-ref="mypoint"/>
<aop:around method="myarround" pointcut-ref="mypoint"/>
</aop:aspect>
</aop:config>
</beans>

10.AspectJ方式在通知中获取切点参数

public class MyAdvice {
public void mybefore(String name,int age){
System.out.println("前置"+name+" "+age);
}
}

配置文件

  <bean id="demo" class="com.mxj.test.Demo"></bean>
<bean id="myadvice" class="com.mxj.advice.MyAdvice"></bean>
<aop:config>
<aop:aspect ref="myadvice">
<aop:pointcut expression="execution(* com.mxj.test.Demo.demo1(String,int)) and args(name,age)" id="mypoint"/>
<aop:before method="mybefore" pointcut-ref="mypoint" arg-names="name,age"/>
</aop:aspect>
</aop:config>

11.使用注解配置AOP(基于Aspect)

  spring不会自动寻找注解,必须告诉spring哪些包下类可能有注解

  (1)引入xmlns:context

  (2)@Component

      相当于<bean/>标签

      如果没有参数,把类名首字母变小写,相当于<bean id=""/>

      @Component("自定义名称")

  (3)实现步骤

    在spring文件中设置注解在哪些包中

 <context:component-scan base-package="com.mxj.advice,com.mxj.test"></context:component-scan>     
 <!-- 
  proxy-target-class
true:使用cglib动态代理
false:使用jdk动态代理
-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>

    在Demo类中添加@Componet

    在方法上添加@Pointcut("")定义切点

@Component
public class Demo {
@Pointcut("execution(* com.mxj.test.Demo.demo1())")
public void demo1() throws Exception{
System.out.println("demo1");
}
}

    在通知类中配置

      @Component类被spring管理

      @Aspect 相当于<aop:aspect/>表示通知方法在当前类中

@Component
@Aspect
public class MyAdvice { @Before("com.mxj.test.Demo.demo1()")
public void mybefore(){
System.out.println("前置");
} @After("com.mxj.test.Demo.demo1()")
public void myafter(){
System.out.println("后置");
} @AfterThrowing("com.mxj.test.Demo.demo1()")
public void mythrow(){
System.out.println("异常通知");
} @Around("com.mxj.test.Demo.demo1()")
public Object myarround(ProceedingJoinPoint p) throws Throwable{
System.out.println("环绕-前置");
Object result = p.proceed();
System.out.println("环绕-后置");
return result;
}
}

12.自动注入

  在Spring配置文件中对象名和ref="id" id名相同使用自动注入,可以不配置<property/>

  两种配置方法:

  (1)在<bean>中通过autowire=""配置,只对<bean>生效

  (2)在<beans>中通过default-autowire=""配置,表示当前文件中所有的<bean>都走全局配置

  (3)autowire=""可取值

    default:默认值,根据全局default-autowire=""值,默认全局和局部都没有配置情况下,相当于no

    no:不自动注入

    byName:通过名称自动注入,在Spring容器中找类的id

    byType:根据类型注入

      spring容器中不可以出现两个相同类型的<bean>

    constructor:根据构造方法注入

      提供对应参数的构造方法(构造方法参数中包含注入对象)

      底层使用byName,构造方法参数名和其他<bean>的id相同

13.Spring中加载properties文件

  (1)在src下新建xxx.properties文件

  (2)在spring配置文件中先引入xmlns:context

      如果需要记载多个文件逗号分割

<context:property-placeholder location="classpath:db.properties"/>

  (3)添加属性文件加载,在<beans>中开启自动注入需要注意的地方:

    SqlSessionFactoryBean的id不能叫做sqlSessionFactory

    修改:把原来通过ref引用替换成value赋值,自动注入只能影响ref,不会影响value赋值

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mxj.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>

14.Spring加载属性文件

  在被Spring管理的类中通过@Value("{key}")取出properties中内容

  (1)添加注解扫描

<context:component-scan base-package="com.mxj.service.impl"></context:component-scan>

  (2)在类中添加

    key和变量名可以不相同

    变量类型任意,只要保证key对应的value能转换成这个类型就可以

@Value("${my.demo}")
private String test;

15.scope属性

  (1)<bean>的属性

  (2)作用:控制对象有效范围(单例,多例等)

  (3)<bean/>标签对应的对象默认是单例的,无论获取多少次都是一个对象

  (4)scope可取值

    singleton:默认值,单例

    prototype: 多例,每次获取重新实例化

    request: 每次请求重新实例化

    session:每个会话对象内,对象是单例的

    application:在application对象内是单例

    global session spring推出一个对象,依赖于spring-webmvc-portlet,类似于session

      

Spring Aop面向切面编程&&自动注入的更多相关文章

  1. 详细解读 Spring AOP 面向切面编程(二)

    本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...

  2. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  3. 【Spring系列】Spring AOP面向切面编程

    前言 接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP. 在开发中,有一些功能行为是通用的,比如.日志管理.安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关 ...

  4. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  5. Spring AOP面向切面编程详解

    前言 AOP即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等.在阅读本文前希望您已经对Spring有一定的了解 注:在能对代码进行添 ...

  6. 详细解读 Spring AOP 面向切面编程(一)

    又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...

  7. spring AOP面向切面编程学习笔记

    一.面向切面编程简介: 在调用某些类的方法时,要在方法执行前或后进行预处理或后处理:预处理或后处理的操作被封装在另一个类中.如图中,UserService类在执行addUser()或updateUse ...

  8. Spring AOP 面向切面编程相关注解

    Aspect Oriented Programming 面向切面编程   在Spring中使用这些面向切面相关的注解可以结合使用aspectJ,aspectJ是专门搞动态代理技术的,所以比较专业.   ...

  9. Spring AOP 面向切面编程入门

    什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...

随机推荐

  1. windows中抓包命令,以及保存为多个文件的方法

    本文主要介绍windows中抓包命令,以及保存为多个文件的方法 说一说保存为多个文件存储数据包这个问题的由来,一般如果长时间抓包,有可能需要等上几个小时,因为这个时候抓包的内容都是存放在内存中的,几个 ...

  2. 题解 「THUPC 2017」小 L 的计算题 / Sum

    题目传送门 题目大意 给出 \(a_{1,2,...,n}\),对于 \(\forall k\in [1,n]\) ,求出: \[\sum_{i=1}^{n}a_i^k \] \(n\le 2\tim ...

  3. Go语言核心36讲(Go语言基础知识五)--学习笔记

    05 | 程序实体的那些事儿(中) 在前文中,我解释过代码块的含义.Go 语言的代码块是一层套一层的,就像大圆套小圆. 一个代码块可以有若干个子代码块:但对于每个代码块,最多只会有一个直接包含它的代码 ...

  4. Billu_b0x2内网渗透(多种提权方法)靶场-vulnhub

    个人博客阅读体验更佳 本次来试玩一下vulnhub上的Billu_b0x2,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场推荐使用N ...

  5. 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

    Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...

  6. Windows10使用技巧

    Windows10配置技巧 新机配置 "我的电脑"图标设置 在桌面右击鼠标=>个性化=>点击左侧"主题"=>点击相关的设置中的"桌面 ...

  7. Convolutional Neural Network-week2编程题2(Residual Networks)

    1. Residual Networks(残差网络) 残差网络 就是为了解决深网络的难以训练的问题的. In this assignment, you will: Implement the basi ...

  8. the Agiles Scrum Meeting 11

    会议时间:2020.4.20 20:00 1.每个人的工作 在这次例会上,我们对上周完成的工作进行了总结. 本周已完成的工作 个人结对项目增量开发组 tq: 创建广播功能 修复纯英文数字可能溢出bug ...

  9. The entitlements specified in your application’s Code Signing Entitlements file do not match those s

    今天给打包 TPshop IOS (搜豹商城) ipa文件 调试运行 xcode运行提示这个错误: The entitlements specified in your application's C ...

  10. Envoy实现.NET架构的网关(四)集成IdentityServer4实现OAuth2认证

    什么是OAuth2认证 简单说,OAuth 就是一种授权机制.数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据.系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使 ...