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. map1

    map2.insert(make_pair("sale", 1)); map2.count("development");//key为development的数 ...

  2. SpringCloud组件架构图

    总结一下spring cloud 的结构: 1.请求统一通过API网关(Zuul)来访问内部服务. 2.网关接收到请求后,从注册中心(Eureka)获取可用服务 3.由Ribbon进行均衡负载后,分发 ...

  3. 前端批量迁移NAS存储

    在实际生产中,老的NAS存储无法扩容,需要迁移到新的存储,种种原因只能前端迁移. 系统:Linux 容量:1.5T 为了减少对生产系统的影响. 1.提前将老的存储数据备份到新的存储上: 2.正试割接存 ...

  4. 【洛谷P3413】萌数

    题目大意:求区间 [l,r] 内萌数的个数,其中萌数定义为数位中存在长度至少为 2 的回文子串的数字. 题解:l, r 都是 1000 位级别的数字,显然是一道数位 dp 的题目,暴力直接去世. 发现 ...

  5. 【洛谷P2922】Secret Message

    题目大意:给定 N 个字符串组成的字典,有 M 个询问,每次给定一个字符串,求字典中有多少个单词为给定字符串的前缀或前缀是给定的字符串. 题解:在 trie 上维护一个 tag 表示有多少字符串以当前 ...

  6. 用jquery控制表单提交

    可以监听表单submit提交事件给form一个id 吧button的type为submit $(form的id).submit(function(){ if(window.confirm('你确定要取 ...

  7. python爬虫及结巴分词《攀登者》影评分析

    <攀登者>影评爬取及分析 0.项目结构 其中simkai.ttf为字体文件,Windows查看系统自带的字体 C:\Windows\Fonts 一.爬取豆瓣影评数据 # -*- codin ...

  8. Codeforces Round #569 (Div. 2) C. Valeriy and Deque

    链接: https://codeforces.com/contest/1180/problem/C 题意: Recently, on the course of algorithms and data ...

  9. 基于gtid复制主要操作记录

    基于gtid复制主要操作记录 一.安装系统依赖包 在主从上都要安装该依赖包. yum -y install perl-DBI yum -y install perl-DBD-MySQL yum -y ...

  10. Python代码2转3、3转2的方法

    众所周知,Python2和Python3不兼容. 那么,假如遇到了超大的工作量,我们是不是需要一行一行地手动去改呢? 当然不是. (一)2转3 Python3.7(顺便提一句,现在装3.7发现好像安装 ...