AOP概念

l  AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码

l  经典应用:事务管理、性能监视、安全检查、缓存 、日志等

l  Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码

l  AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

Aop的实现原理

l aop底层将采用代理机制进行实现。

专业术语

1.target:目标类,需要被代理的类。例如:UserService

2.Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法

3.PointCut 切入点:已经被增强的连接点。例如:addUser()

4.advice 通知/增强,增强代码。例如:after、before

5. Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.

6.proxy 代理类

7. Aspect(切面): 是切入点pointcut和通知advice的结合

一个线是一个特殊的面。

一个切入点和一个通知,组成成一个特殊的面。

1.execution()  用于描述方法 【掌握】

语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)

修饰符,一般省略

public             公共方法

*                    任意

返回值,不能省略

void               返回没有值

String             返回值字符串

*                   任意

包,[省略]

com.itheima.crm                   固定包

com.itheima.crm.*.service       crm包下面子包任意 (例如:com.itheima.crm.staff.service)

com.itheima.crm..                 crm包下面的所有子包(含自己)

com.itheima.crm.*.service..     crm包下面任意子包,固定目录service,service目录任意包

类,[省略]

UserServiceImpl                    指定类

*Impl                                   以Impl结尾

User*                                   以User开头

*                                         任意

方法名,不能省略

addUser                              固定方法

add*                                   以add开头

*Do                                     以Do结尾

*                                         任意

(参数)

()                                        无参

(int)                                     一个整型

(int ,int)                               两个

(..)                                       参数任意

throws ,可省略,一般不写。

2.within:匹配包或子包中的方法(了解)

within(com.itheima.aop..*)

3.this:匹配实现接口的代理对象中的方法(了解)

this(com.itheima.aop.user.UserDAO)

4.target:匹配实现接口的目标对象中的方法(了解)

target(com.itheima.aop.user.UserDAO)

5.args:匹配参数格式符合标准的方法(了解)

args(int,int)

6.bean(id)  对指定的bean所有的方法(了解)

bean('userServiceId')

=======================================================================================

实例 :AOP基于xml配置开发

UserAOP.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="aspectUser" class="com.spring_aop1.AspectUser"></bean>
<bean id="user" class="com.spring_aop1.User"></bean> <aop:config>
<!-- expression="execution(返回值 包名.类名.方法名(参数类型)) id="任意":切入点名 -->
<aop:pointcut expression="execution(* com.spring_aop1.*.*(..))" id="myPointcut"/> <aop:aspect ref="aspectUser">
<aop:before method="password" pointcut-ref="myPointcut"/>
<aop:after-returning method="after" pointcut-ref="myPointcut" returning="obj"/>
<!-- <aop:around method="around" pointcut-ref="myPointcut" /> -->
<aop:around method="aroundR" pointcut-ref="myPointcut" /> <aop:after-throwing method="throwable" pointcut-ref="myPointcut" throwing="e"/>
</aop:aspect> </aop:config> </beans>

User.java

 package com.spring_aop1;

 public class User {

     private String str;

     public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
} public void insert(){
System.out.println("insert====ok");
}
public void delete(){
System.out.println("delete====ok");
}
public void update(){
System.out.println("update====ok");
}
public void selete(){
System.out.println("insert====ok");
} }

AspectUser.java

 package com.spring_aop1;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint; public class AspectUser { /**
* 定义一个前置通知
* */
public void password(){
System.out.println("前置通知:密码验证=====成功");
} /**
* 定义一个后置通知(可得方法返回值)
* @param jp execution(void com.spring_aop.User.save())
* @param obj
* */
public void after(JoinPoint jp,Object obj){
String name = jp.getSignature().getName(); System.out.println("后置通知:after获取一个返回值类型====切入点");
System.out.println("after返回值信息为:"+name);
} /**
* 定义一个环绕通知
* @param pjp execution(void com.spring_aop.User.save())
* */
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知:around执行环绕通知前执行");
pjp.proceed();
System.out.println("环绕通知:around执行环绕通知后执行");
}
/**
* 定义一个环绕通知(可得方法返回值)
* @throws Throwable
* */
public Object aroundR(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知:around执行环绕通知前执行");
Object obj = pjp.proceed();
System.out.println("环绕通知:around执行环绕通知后执行"); String s = pjp.getSignature().getName();
System.out.println("around返回值的类型:"+obj+" around返回方法名:"+s);
return obj;
} /**
* 定义一个异常通知(可得方法返回值)
* @throws Throwable
* */
public void throwable(JoinPoint jp,Throwable e){
System.out.println("到我这里来,说明 你发生了异常======");
} }

Test.java

 package com.spring_aop1;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserTest { public static void main(String[] args) { String str = "com/spring_aop1/UserAop.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(str); User user = (User)context.getBean("user");
user.insert(); } }

实例 :AOP基于注解开发

UserAOP.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"
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="com.spring_aop2"></context:component-scan> <!-- 添加AOP的注解扫描 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>

User.java

 package com.spring_aop2;

 import org.springframework.stereotype.Component;

 @Component(value="user")
public class User { private String str; public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
} public void insert(){
System.out.println("insert====ok");
}
public void delete(){
System.out.println("delete====ok");
}
public void update(){
System.out.println("update====ok");
int i = 1/0;
}
public void selete(){
System.out.println("insert====ok");
} }

AspectUser.java

 package com.spring_aop2;

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Component("aspectUser") //组件
@Aspect //声明这是一个切面类
public class AspectUser { /**
* <aop:pointcut
* expression="execution(* com.spring_aop2.*.*(..))"
* id="myPointcut" />
* */
@Pointcut("execution(* com.spring_aop2.*.*(..))")
private void myPoint(){} /**
* 定义一个前置通知
* */
@Before("execution(* com.spring_aop2.*.*(..))") //指向切入点的Id(私有方法的方法名)
public void password(){
System.out.println("前置通知:密码验证=====成功");
} /**
* 定义一个后置通知(可得方法返回值)
* @param jp execution(void com.spring_aop.User.save())
* @param obj
* */
@AfterReturning(value="myPoint()",returning="obj")
public void after(JoinPoint jp,Object obj){
String name = jp.getSignature().getName(); System.out.println("后置通知:获取一个返回值类型====切入点");
System.out.println("after返回值信息为:"+name);
} /**
* 定义一个环绕通知
* @param pjp execution(void com.spring_aop.User.save())
* */
@Around("execution(* com.spring_aop.*.*(..))")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知:around执行环绕通知前执行");
pjp.proceed();
System.out.println("环绕通知:around执行环绕通知后执行");
}
/**
* 定义一个环绕通知(可得方法返回值)
* @throws Throwable
* */
public Object aroundR(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知:around执行环绕通知前执行");
Object obj = pjp.proceed();
System.out.println("环绕通知:around执行环绕通知后执行"); String s = pjp.getSignature().getName();
System.out.println("around返回值的类型:"+obj+" around返回方法名:"+s);
return obj;
} /**
* 定义一个异常通知(可得方法返回值)
* @throws Throwable
* */
@AfterThrowing(value="myPoint()",throwing="e")
public void throwable(JoinPoint jp,Throwable e){
System.out.println("到我这里来,说明 你发生了异常======");
} }

Test.java

 package com.spring_aop2;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserTest { public static void main(String[] args) { String str = "com/spring_aop2/UserAop.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(str); User user = (User)context.getBean("user");
user.insert();
//user.update(); } }

spring(二) AOP注入的更多相关文章

  1. spring(二) AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  2. Spring之AOP二

    在Spring之AOP一中使用动态代理将日志打印功能注入到目标对象中,其实这就是AOP实现的原理,不过上面只是Java的实现方式.AOP不管什么语言它的几个主要概念还是有必要了解一下的. 一.AOP概 ...

  3. Spring(二)--IoC&AOP

    IOC 一.IOC概述: 一般指控制反转(inversion of Control),把创建对象的权利交给框架,Ioc容器控制对象,是框架的重要特征,并非是面向对象编程的专用术语.它包括依赖注入(DI ...

  4. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...

  5. Spring学习笔记(二)Spring基础AOP、IOC

    Spring AOP 1. 代理模式 1.1. 静态代理 程序中经常需要为某些动作或事件作下记录,以便在事后检测或作为排错的依据,先看一个简单的例子: import java.util.logging ...

  6. 框架应用:Spring framework (二) - AOP技术

    基础概念 线程中的方法栈 java程序虚拟机启动时会载入程序码,虚拟机会为每一条正在运行的线程生成一个方法调用栈,线程以方法运行为执行单位. AOP概念以及目标 AOP是面向切面编程,其实就是在不修改 ...

  7. spring学习(二) ———— AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  8. SpringBoot系列: 理解 Spring 的依赖注入(二)

    ==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @B ...

  9. Spring中AOP主要用来做什么。Spring注入bean的方式。什么是IOC,什么是依赖注入

    Spring中主要用到的设计模式有工厂模式和代理模式. IOC:Inversion of Control控制反转,也叫依赖注入,通过 sessionfactory 去注入实例:IOC就是一个生产和管理 ...

  10. 09 Spring框架 AOP (二) 高级用法

    上一篇文章我们主要讲了一点关于AOP编程,它的动态考虑程序的运行过程,和Spring中AOP的应用,前置通知,后置通知,环绕通知和异常通知,这些都是Spring中AOP最简单的用法,也是最常用的东西, ...

随机推荐

  1. mysql 的主从

    MySQL的Replication(英文为复制)是一个多MySQL数据库做主从同步的方案,特点是异步复制,广泛用在各种对MySQL有更高性能.更高可靠性要求的场合.与之对应的是另一个同步技术是MySQ ...

  2. AUC计算方法

    本质是ROC曲线下的面积,ROC曲线x轴是误判率/误报率(false positive rate),y轴是准确率/命中率(true positive rate). AUC是ROC曲线与横轴所围的面积. ...

  3. SQL注入--反引号

    反引号是个比较特别的字符,下面记录下怎么利用 0x00 SQL注入 反引号可利用在分隔符及注释作用,不过使用范围只于表名.数据库名.字段名.起别名这些场景,下面具体说下 1)表名 payload:se ...

  4. [易学易懂系列|rustlang语言|零基础|快速入门|(12)|Enums枚举]

    [易学易懂系列|rustlang语言|零基础|快速入门|(12)] 有意思的基础知识 Enums 今天我们来讲讲枚举. 在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者 ...

  5. 调试dcc 试图将u-boot放入ocm运行碰到的问题

    1. 起因: gd->mon_len = (ulong)&__bss_end - (ulong)_start; 在u-boot.map中查找,发现__bss_end并不是u-boot.b ...

  6. element-ui + redis + mongo + nuxt

    用户注册: let {username,password} = req.body; let u = await UserModel.findOne({username}); if(u){ res.js ...

  7. 怎么画一条0.5px的边

    编者按:本文由人人网FED发表于掘金,并已授权奇舞周刊转载 什么是像素? 像素是屏幕显示最小的单位,在一个1080p的屏幕上,它的像素数量是1920 1080,即横边有1920个像素,而竖边为1080 ...

  8. MyEclipse使用教程:unattended安装

    [MyEclipse CI 2019.4.0安装包下载] 以下内容适用于2013及以上版本. 运行无提示安装程序 1. 创建一个unattended response文件. 2. 要激活unatten ...

  9. 稀疏数组SparseArray

    1 实际需求 1.1 需求提出 编写五子棋程序,有存盘退出和续上盘的功能. 实现思路: 存盘退出: 定义一个二维数组,默认值是0,黑子表示1,蓝子表示2,然后将二维数组通过流存储到文件中. 换言之:五 ...

  10. SpringBoot + kaptcha 生成、校对 验证码

    1.引入 kaptcha 的 Maven 依赖 <dependency> <groupId>com.github.penggle</groupId> <art ...