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. memcached和redis的区别

    memcache和redis区别 memcach简介 Memcache时一个内存对象缓存系统,用于加速动态web应用程序,减轻数据库负载.它可以应对任意多个连接,使用非阻塞的网络I/O, 工作机制: ...

  2. C#文件路径操作总结

    一.获取当前文件的路径 1.   System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName     获取模块的完整路径,包括 ...

  3. 【gin-vue-admin】 使用go和vue 快速搭建一个项目模板

    gin-vue-admin gin+vue开源快速项目模板 项目地址:https://github.com/piexlmax/gin-vue-admin 增加了 micro-service-test分 ...

  4. 一、Linux 设备驱动介绍及开发环境搭建

    1.1 Linux 设备驱动介绍 1.1.1 分类及特点 计算机系统的硬件主要由 CPU.存储器和外设组成. 当前 CPU 内部都集成有存储器和外设适配器. 外设适配器有入 UART.IIC 控制器. ...

  5. ARM仿真器之驱动黄色惊叹号

    JLink CDC UART PORT 黄色惊叹号 Windows 无法验证此设备所需的驱动程序的数字签名.某软件或硬件最近有所更改,可能安装了签名错误或损毁的文件,或者安装的文件可能是来路不明的恶意 ...

  6. UIWebView半透明设置

    在项目中有时候需要弹出活动弹框,由于原生的样式会固定,所以考虑h5显示,这就需要webView的背景色半透明,如图: 让 UIWebView 背景透明需要以下设置

webView.backgroun ...

  7. IDL_MCTK(MODIS Conversion Toolkit)

    1.CONVERT_MODIS_DATA CONVERT_MODIS_DATA [,IN_FILE= | | }] [,GEOLOC_FILE= | | }] [,CALIB_METHOD={ | | ...

  8. bootstrap-table.min.js不同版本返回分页参数不同的问题

    1.使用公司用的bootstrap-table.min.js ,刚开始bootstrap-table分页参数是这么写的 分页查询参数: 后端代码为: Result返回类的参数为list,以及total ...

  9. 浅析为什么用高阶组件代替 Mixins

    转载来源 感谢分享 Mixins 引入了无形的依赖 应尽量构建无状态组件,Mixin 则反其道而行之 Mixin 可能会相互依赖,相互耦合,不利于代码维护 不同的 Mixin 中的方法可能会相互冲突 ...

  10. day2计算机基础作业题

    1.什么是编程? 编程就是程序员用某种编程语言的语法格式将将自己脑中想让计算机做的事情写成文件.所以编程的结果就是一堆的文件,一堆文件就是的程序. 2.计算机的组成: 1).CPU 其中CPU又分为控 ...