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. Git 查看远端仓库地址

    git remote -v

  2. python virtualenv和virtualenv的使用

    首先下面的步骤我都是在windows下执行,Python2.7,pip==19.1.1 1.安装virtualenv pip install virtualenv 2.新建virtualenv vir ...

  3. PAT Basic 1042 字符统计 (20 分)

    请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母, ...

  4. MapReduce计数程序(自主复习)

    1.MyWordCount类 注意: 1.本机+测试,两个注释都放开 2.本机跑集群,要开异构平台为true 3.集群跑,把两个注释都注起来,然后在集群上面跑 package com.littlepa ...

  5. [CQOI2013]新Nim游戏(博弈论,线性基)

    [CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根 ...

  6. java课堂作业3 动手动脑

    第一题 测试一下代码查看输出结果 public class InitializeBlockDemo { /** * @param args */ public static void main(Str ...

  7. redis高可用(一)主从复制

    主从复制 读写分离 https://blog.csdn.net/u014691098/article/details/82391608

  8. Python面向对象的三大特性之继承和组合

    继承和组合 一.组合 组合:组合指的是,在一个类中以另外一个类的对象(也就是实例)作为数据属性,称为类的组合 也就是说:一个类的属性是另一个类的对象,就是组合 例子: 圆环是由两个圆组成的,圆环的面积 ...

  9. 【GDOI2013模拟4】贴瓷砖

    题目 A镇的主街是由N个小写字母构成,镇长准备在上面贴瓷砖,瓷砖一共有M种,第i种上面有Li个小写字母,瓷砖不能旋转也不能被分割开来,瓷砖只能贴在跟它身上的字母完全一样的地方,允许瓷砖重叠,并且同一种 ...

  10. kafka——分布式的消息队列系统

    总听公司人说kafka kafka... 所以这玩意到底是个啥? 好像是一个高级版的消息队列,什么高吞吐量,数据持久,消息均衡,emmm https://blog.csdn.net/nawenqian ...