Sprin框架的学习(课时七)SpringAop的学习
目录
2022年9月9号Sprin框架的学习(课时七)Aop项内容设计23设计模式中的静态代理模式而在SpringAop中实现的时动态代理模式
第一部分 了解Java23模式的基本概念从下面的概念去理解扩展知识
1 什么是设计模式:
2 学习设计模式的意义:
3 GoF23设计模式指哪些:每种模式体现每一种解决问题的思想能力
4 0PG七大原则
5 Java的23设计模式的以下的内容大概介绍:
1 创建型模式
2 结构型模式:把类或对象结合在一起形成一个更大的结构。
3 行为型模式:类和对象如何交互,及划分责任和算法。
第二部分 代理模式:为其它对象提供一个代理以便控制这个对象的访问 进入静态代理模式的学习 这里会用两个案例来讲述什么是 代理模式 这里的每种模式是一种思维 要读者去理解其思维的能力
下面用几张图来理解什么是代理模式哦
案例一 抽象角色一般是接口或者是实现类 中介
房东 也要出租房子
上面是运行结果 思考一下上面的代码是不是可以优化呀!
案例二
Java动态代理 四种方式
案例三:
案例三和案例一对比你会发现不同哦! 因为案例三实现了动态代理
案例一
在案例三的基础上来了案例四 在动态代理中总结出了公式
动态代理的总结:
第三部分 Spring框架中的Aop@理解Aop的基础概念@了解Aop开发的三种方式 备注Spring框架的学习基于了解Maven项目的前提下开始的哦!
上面的代码是Com.Spring项目的pom.xml文件要的依赖
上面的代码是Spring-01-aop项目的pom.xml文件要的依赖
在SpringAop中扩展一个知识execution表达式这个是关于SpringAop的一个知识点下面的内容只是扩展内容
SpringAop书写的三种方式 注解 配置文件 自定义类中接下来我们来实战一下吧
方案一 注解的方式来表达学习 Aop
方式案二 利用自己自定义的类中来表达
方案三 利用原始方法在配置文件中
2022年9月9号Sprin框架的学习(课时七)Aop项内容设计23设计模式中的静态代理模式而在SpringAop中实现的时动态代理模式
第一部分 了解Java23模式的基本概念从下面的概念去理解扩展知识
1 什么是设计模式:
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、
可维护性、可读性、稳健性以及安全性的解决方案。1995 年,GoF (Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,
共收录了23 种设计模式,从此树立了软件设计模式领域的里程碑,人称.「GoF设计模式」
2 学习设计模式的意义:
- 设计模式的本质是面向对象设计原则的实际运用, 是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。
- 正确使用设计模式具有以下优点:
- 可以提高程序员的思维能力、编程能力和设计能力。
- 使程序设计更加标准化、 代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
- 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。
- 个人总结 增强自己编码的思维能力,以另外的一种思维解决生活中的问题。
3 GoF23设计模式指哪些:每种模式体现每一种解决问题的思想能力
- ◆创建型模式:
- ◆单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
- ◆结构型模式:
- ◆适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式◆行为型模式:
- ◆模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式。
4 0PG七大原则
- ◆开闭原则:对扩展开放,对修改关闭
- ◆里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立
- ◆依赖倒置原则:要面向接口编程,不要面向实现编程。
- ◆单一职责原则:控制类的粒度大小、将对象解耦、 提高其内聚性。
- ◆接口隔离原则:要为各个类建立它们需要的专用接口
- ◆迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。
- ◆合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
5 Java的23设计模式的以下的内容大概介绍:
1 创建型模式
- 创建型模式 对象实例化的模式,创建型模式用于解耦对象的实例化过程。
- 单例模式:某个类智能有一个实例,提供一个全局的访问点。
- 工厂模式:一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
- 抽象工厂模式:创建相关或依赖对象的家族,而无需明确指定具体类。
- 建造者模式:封装一个复杂对象的创建过程,并可以按步骤构造。
- 原型模式:通过复制现有的实例来创建新的实例。
2 结构型模式:把类或对象结合在一起形成一个更大的结构。
- 装饰器模式:动态的给对象添加新的功能。
- 代理模式:为其它对象提供一个代理以便控制这个对象的访问。
- 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
- 适配器模式:将一个类的方法接口转换成客户希望的另一个接口。
- 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
- 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
- 享元模式:通过共享技术来有效的支持大量细粒度的对象。
3 行为型模式:类和对象如何交互,及划分责任和算法。
- 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
- 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
- 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
- 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
- 观察者模式:对象间的一对多的依赖关系。
- 仲裁者模式:用一个中介对象来封装一系列的对象交互。
- 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
- 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
- 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
- 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
- 访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。
第二部分 代理模式:为其它对象提供一个代理以便控制这个对象的访问 进入静态代理模式的学习 这里会用两个案例来讲述什么是 代理模式 这里的每种模式是一种思维 要读者去理解其思维的能力
代理模式的好处:
●可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务●公共也就就交给代理角色!实现了业务的分工!
●公共业务发生扩展的时候,方便集中管理!
缺点:
●一个真实角色就会产生-个代理角色;代码量会翻倍~开发效率会变低~
下面用几张图来理解什么是代理模式哦
![](/assets/blank.gif)
案例一
![](/assets/blank.gif)
案例二
![](/assets/blank.gif)
角色分析
案例一 抽象角色一般是接口或者是实现类 中介
package coms.Design.Mode.Demo1;/*** 代理模式*/
public interface Rent {public void rent();public void x();
}
package coms.Design.Mode.Demo1;/*** 中介这个角色*/public class Proxy implements Rent {private Host host;public Proxy() {}public Proxy(Host host) {this.host = host;}@Overridepublic void rent() {host.rent();}@Overridepublic void x() {host.x();}//看房子public void seeHse() {System.out.println("中介带你看房子");}//收费public void money() {System.out.println("收中介费");}//合同public void Heh() {System.out.println("合同");}public void Phone(){System.out.println("中介带电话给房东明确交房的时间");}}
房东 也要出租房子
package coms.Design.Mode.Demo1;
//房东 租房
public class Host implements Rent{@Overridepublic void rent() {System.out.println("房东要租房子,要出租房子");}@Overridepublic void x() {System.out.println("我要执行的是X方法");}
}
package coms.Design.Mode.Demo1;/*** 操作的内容单一*/
public class Client {public static void main(String[] args) {Host host=new Host();
// host.rent();//代理Proxy proxy = new Proxy(host);proxy.rent();proxy.seeHse();proxy.money();proxy.Heh();proxy.Phone();proxy.x();}}
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:D:\IDEA\com.text\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=58971:D:\IDEA\com.text\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;D:\SSM\com.JavaBasics\out\production\com.JavaBasics" coms.Design.Mode.Demo1.Client
房东要租房子,要出租房子
中介带你看房子
收中介费
合同
中介带电话给房东明确交房的时间
我要执行的是X方法Process finished with exit code 0
上面是运行结果 思考一下上面的代码是不是可以优化呀!
案例二
package coms.Design.Mode.Demo02;public interface UserService {void adds();void delete();void update();void query();
}
package coms.Design.Mode.Demo02;/*** 正式的对象*/
public class UserServiceImp implements UserService{@Overridepublic void adds() {System.out.println("增加一条数据");}@Overridepublic void delete() {System.out.println("删除一条数据");}@Overridepublic void update() {System.out.println("修改一条数据");}@Overridepublic void query() {System.out.println("查询一条数据");}
}
package coms.Design.Mode.Demo02;public class UserServiceProxy implements UserService {private UserServiceImp userService;public void setUserService(UserServiceImp userService){this.userService=userService;}@Overridepublic void adds() {log("增加");userService.adds();}@Overridepublic void delete() {log("修改");userService.delete();}@Overridepublic void update() {userService.update();}@Overridepublic void query() {userService.query();}//日public void log(String msg){System.out.println("使用了"+msg+"msg想方法");}
}
Java动态代理 四种方式
案例三:
JDK动态代理:运行期动态的创建代理类,只支持接口。
ASM:一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解;cglib基于ASM实现动态代理。
javassist:一个开源的分析、编辑和创建Java字节码的类库(源码级别的类库)。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类;
bytebuddy:一个更高层次操作字节码的工具包。
![](/assets/blank.gif)
Aop代码底层的本质是动态代理
package coms.Design.Mode.Demo03;/*** 代理模式*/
public interface Rent {public void rent();
}
package coms.Design.Mode.Demo03;//房东 租房
public class Host implements Rent {@Overridepublic void rent() {System.out.println("房东要租房子,要出租房子");}
}
package coms.Design.Mode.Demo03;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 等会用这个类自动生成代理类*/
//处理代理实例并返回的结果
public class ProxyInvocationHandler implements InvocationHandler {//被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}//生成代理类 固定代码public Object getProxy() {
// 类的位置 接口 应用对象return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动代代理的机制本质又是反射机制first();setHandler();Object result = method.invoke(rent, args);farer();end();return result;}public void setHandler(){System.out.println("中介在看房子");}public void farer(){System.out.println("看完后收中介费");}public void first(){System.out.println("去中介哪里找房子");}public void end(){System.out.println("收合同");}}
案例三和案例一对比你会发现不同哦! 因为案例三实现了动态代理
案例一
//案例一
public interface Rent {
public class Host implements Rent{
public class Proxy implements Rent {
//案例三
public interface Rent {
public class Host implements Rent {
public class ProxyInvocationHandler implements InvocationHandler {
在案例三的基础上来了案例四 在动态代理中总结出了公式
package coms.Design.Mode.Demo04;import coms.Design.Mode.Demo03.Rent;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** 等会用这个类自动生成代理类*/
//处理代理实例并返回的结果
public class ProxyInvocationHandler implements InvocationHandler {//被代理的接口private Object target;public void setTarget(Object target) {this.target = target;}//生成代理类 固定代码public Object getProxy() {
// 类的位置 接口 应用对象return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动代代理的机制本质又是反射机制log(method.getName());Object result = method.invoke(target, args);return result;}//全自动化public void log(String msg){System.out.println("执行了陌陌"+msg+"方法");}}
![](/assets/blank.gif)
案例四的运行结果
动态代理的总结:
●动态代理和静态代理角色- -样
●动态代理的代理类是动态生成的,不是我们直接写好的!
●动态代理分为两大类:基于接口的动态代理 ,基于类的动态代理。基于接口-- JDK动态代理[我们在这里使用]
) 基于类: glib
java字节码实现: javasist
需要了解两个类: Proxy: 代理,InvocationHandler:
第三部分 Spring框架中的Aop@理解Aop的基础概念@了解Aop开发的三种方式 备注Spring框架的学习基于了解Maven项目的前提下开始的哦!
提供声明式事务;允许用户自定义切面==
●横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等....
●切面(ASPECT) :横切关注点被模块化的特殊对象。即,它是一个类。
●通知(Advice) :切面必须要完成的工作。即,它是类中的一-个方法。
●目标(Target) :被通知对象。
●代理(Proxy) :向目标对象应用通知之后创建的对象。
●切入点(PointCut) :切面通知执行的“地点”的定义。
●连接点(JointPoint) :与切入点匹配的执行点。
![](/assets/blank.gif)
项目的结构
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>spring0909</groupId><artifactId>Com.Spring</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>Spring-01-aop</module></modules><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.0.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>
上面的代码是Com.Spring项目的pom.xml文件要的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>Com.Spring</artifactId><groupId>spring0909</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>Spring-01-aop</artifactId><dependencies><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency></dependencies></project>
上面的代码是Spring-01-aop项目的pom.xml文件要的依赖
在SpringAop中扩展一个知识execution表达式这个是关于SpringAop的一个知识点下面的内容只是扩展内容
一、Aspect切入点语法定义
在使用spring框架配置AOP的时候,不管是通过XML配置文件形式,还是注解的方式都需要定义pointcut(切入点),pointcut称之为切入点。例如 :
定义切入点表达式 :
execution (* com.sample.service.impl..*.*(..))
上面的execution()是最常用的切点函数,其语法如下所示:整个表达式可以分为五个部分
1、execution():表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点分别表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..) :第三个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
下面给出一些常见切入点表达式的例子: 借鉴(https://smallbee.iteye.com/blog/2213078)任意公共方法的执行:
execution(public * *(..)) : 表明任何返回类型、类名和参数的任何公共方法都将被通知。
任何一个以"set"开始的方法的执行:execution(* set*(..))
AccountService接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意类的任意方法的执行:execution(* com.xyz.service..*.*(..))
二、如何定义多个切入点,在多个表达式之间如何表示
使用 ||, or表示 或
使用 &&,and表示 与
使用not,!表示 非三、execution表达式
1、匹配指定包下所有类方法 :execution(* com.baidu.dao.*(..)) 不包含子包
2. 匹配指定包以及及指定包下面的子包所有类 :execution(* com.baidu.dao..*(..)) ..*表示当前包、子孙包下所有类
3、匹配指定类所有方法 :execution(* com.baidu.service.UserService.*(..))
4、匹配实现特定接口所有类方法 :execution(* com.baidu.dao.GenericDAO+.*(..))
5、匹配所有save开头的方法 :execution(* save*(..))
另外,签名可分为类型签名和方法签名,下面介绍两种类型 的区别,参考自: https://www.jianshu.com/p/1ff6c1edbb7b
四、类型签名表达式
为了根据类型(比如接口、类名或者包名过滤方法),SpringAOP提供了Within关键字。类型签名模式如下,其中可以使用package name或者class name替换type name。Within(<type name>)
接下来列举一些类型签名用法的示例:within(net.yangki..*):该通知将匹配net.yangki包及其子包中所有类中的所有方法。
within(net.yangki.spring.demo.MyService):该通知将匹配MyService类中的所有方法。
within(MyServiceInterface+):该通知将匹配所有实现了MyServiceInterface接口的类的所有方法。
within(net.yangki.spring.demo.MyBaseService+):该通知将匹配MyBaseService类以及其子类的所有方法。
五、方法签名表达式
如果想根据方法签名进行过滤,可以使用关键字execution。模式如下:execution(<scope><return-type><fully-qualified-class-name>.*(parameters))
此时,对于与给定的作用域、返回类型、完全限定类名以及参数相匹配的方法,都会应用指定的通知。方法的作用域可以是公共的、保护的或者私有的。如果不想使用参数过滤,可以指定两个点..,以表明方法可以接受任何数量和任何类型的参数。下面对方法签名的示例进行了简单的概述:execute(* net.yangki.soring.demo.MyBean.*(..)):该通知将匹配MyBean中的所有方法。
execute(public * net.yangki.spring.demo.MyBean.*(..)):该通知将匹配MyBean中的所有公共方法。
execute(public String net.yangki.spring.demo.MyBean.*(..)):该通知将匹配MyBean中的所有返回值为String类型的公共方法。
execute(public * net.yangki.spring.demo.MyBean.*(long,..)):该通知将匹配MyBean第一个参数被定义为long的所有公共方法。
六、其他替代的切入点指示符
该部分将举例SpringAOP所支持的指示符。AOP仅支持在其他AOP项目中可用的指示符的一个子集。bean(* Service):根据名称使用关键字bean进行过滤。该切入点表达式将与名称中带有后缀Service的Bean相匹配。
@annotation(net.yangki.spring.demo.MarkerMethodAnnotation):根据所应用的注解对方法进行过滤。该切入点表达式表明使用了MarkerMethodAnnotation注解的方法将被通知。
within(net.yangki.spring.demo.MarkerAnnotation):当带有关键字within的切入点表达式与一个包、类或者接口相匹配时,可以根据类所使用的注解限制对类的过滤。此时,使用了MarkerMethodAnnotation注解的类将被@within关键字通知。
This(net.yangki.spring.demo.MarkerInterface):该切入点表达式将对任何实现了MarkerInterface接口的代理对象的方法进行过滤。
七、通配符
在定义表达式时,还可以使用通配符。比如*、..或者+。如下表通配符 定义
.. 该通配符匹配方法定义中的任何数量的参数,此外还匹配类定义中任何数量的包
+ 该通配符匹配给定类的任何子类
* 该通配符匹配任何数量的字符
SpringAop书写的三种方式 注解 配置文件 自定义类中接下来我们来实战一下吧
方案一 注解的方式来表达学习 Aop
<?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:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--注册Bean--><bean id="userservice" class="com.service.UserServiceImp"></bean><bean id="log" class="log.Log"></bean><bean id="afterlog" class="log.Afterlog"></bean><!--方式三 --><bean id="annotationPointCut" class="diy.AnnotationPointCut"></bean><!--代理Aop注解支持 JDK proxy-target-class="false" --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
package diy;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;/*** 方式三 使用注解方式实现Aop*/
//@Aspect 标注这个类是切面/*** @Before("execution(* com.service.UserServiceImp.*(..))")* @After("execution(* com.service.UserServiceImp.*(..))")*/
@Aspect
public class AnnotationPointCut {@Before("execution(* com.service.UserServiceImp.*(..))")public void before() {System.out.println("==============方法执行前=================");}@After("execution(* com.service.UserServiceImp.*(..))")public void after() {System.out.println("==============方法执行后==================");}@Around("execution(* com.service.UserServiceImp.*(..))")public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println("在环绕增强中,我们可以定义一个参数,代表我们要获取处理的切入点");Object o = jp.proceed();System.out.println("环绕前");}
}
方式案二 利用自己自定义的类中来表达
package diy;/*** 自定义类*/
public class DiyPointcut {public void before(){System.out.println("==============方法执行前=================");}public void after(){System.out.println("==============方法执行后==================");}public void see(){System.out.println("SpringAop开发第二种方案自定义类");}
}
<bean id="diy" class="diy.DiyPointcut"></bean><aop:config><!--自定义切面 ref 要引用的类--><aop:aspect ref="diy"><!--切入点--><aop:pointcut id="point" expression="execution(* com.service.UserServiceImp.*(..)))"/><!--通知--><aop:before method="before" pointcut-ref="point"></aop:before><aop:after method="after" pointcut-ref="point"></aop:after><aop:after method="see" pointcut-ref="point"></aop:after></aop:aspect></aop:config>
方案三 利用原始方法在配置文件中
package com.service;public interface UserService {public void add();public void delete();public void update();public void query();
}
package com.service;public class UserServiceImp implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("修改了一个用户");}@Overridepublic void query() {System.out.println("查询了一个用户");}
}
package log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class Afterlog implements AfterReturningAdvice {/*** 多了一个返回值* @param o* @param method* @param objects* @param o1* @throws Throwable*/@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("执行了"+method.getName()+"返回了"+o);}
}
package log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class Log implements MethodBeforeAdvice {//Method 要执行的目标对象方法//orgs 参数//target 目标对象@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");}
}
import com.service.UserService;
import com.service.UserServiceImp;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MaTest {public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口UserService userservice = (UserService) applicationContext.getBean("userservice");userservice.add();}
}
import com.service.UserService;
import com.service.UserServiceImp;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MaTest {public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口UserService userservice = (UserService) applicationContext.getBean("userservice");userservice.add();userservice.delete();userservice.query();userservice.update();}
}
Sprin框架的学习(课时七)SpringAop的学习相关推荐
- 爬虫入门学习(七)IP学习与代理池构建
爬虫入门学习(七)IP学习与代理池构建 1 IP简介 2 IP被封的原因 3 应对IP被封的策略 3.1 伪造User-Agent 3.2 设置线程等待sleep() 3.3 伪造Cookies 3. ...
- [学习笔记] python深度学习---第七章 深度学习最佳实践
一.联合学习 如果只有元数据,那么可以使用one-hot编码,然后用密集连接网络来预测价格.如果只有文本描述,那么可以使用循环神经网络或一维卷积神经网络.如果只有图像,那么可以使用二维卷积神经网络.但 ...
- jQuery框架学习第七天:jQuery动画–jQuery让页面动起来!
jQuery框架学习第一天:开始认识jQuery jQuery框架学习第二天:jQuery中万能的选择器 jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQu ...
- Java IO流学习总结七:Commons IO 2.5-FileUtils
Java IO流学习总结七:Commons IO 2.5-FileUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/5497 ...
- Java回炉学习(七)
Java回炉学习(七) 1. 泛型 泛型的好处:1. 编译时,检查添加元素的类型,提高了安全性 2. 减少了类型转换的次数,提高效率 //泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型 ...
- ESP32学习笔记(七) 复位和时钟
ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...
- 大数据学习系列:Hadoop3.0苦命学习(七)
传送门: 大数据学习系列:Hadoop3.0苦命学习(一) 大数据学习系列:Hadoop3.0苦命学习(二) 大数据学习系列:Hadoop3.0苦命学习(三) 大数据学习系列:Hadoop3.0苦命学 ...
- 李弘毅机器学习笔记:第七章—深度学习的发展趋势
李弘毅机器学习笔记:第七章-深度学习的发展趋势 回顾一下deep learning的历史: 1958: Perceptron (linear model) 1969: Perceptron has l ...
- 第七周编程学习笔记(4.17-4.23)
目录 第一天4.17 星期一 anaconda环境配置 深度学习基础 第二天4.18 星期二 AI软件.sketchup.数据库与数据结构 第三天4.19 星期三 论文表格和图片 ...
最新文章
- 乐观锁与悲观锁——解决并发问题
- 学以致用一:得到数组的最后一个元素。
- 最高5000倍加速模拟物理世界,育碧在修复bug上又进一步
- Hibernate实现limit查询报错 unexpected token: ? near line 1, column 30 [from cn.com.bean.Layer limit ? ,
- Node.js HTTPS
- java开发爱恩斯坦棋,爱恩斯坦棋计算机博弈关键技术研究
- Linux Load Balancing之NAT与DR模型
- 开源Easydarwin流媒体服务器Windows编译、配置、部署
- 门槛低的行业看天赋,门槛高的行业看毅力
- C++数据类型之结构体的练习(用到结构体的赋值,利用结构体元素排序以及查找)
- 【渝粤教育】国家开放大学2018年秋季 0463-21T英语语音 参考试题
- 会计计算机学什么软件有哪些,会计学习软件
- 酷客数据python基础实战答案_英语听力练习_日语_韩语_法语听力训练网站-沪江听力酷...
- [软件安装] 动态图像录制工具LICEcap
- 高级驾驶辅助系统ADAS简介
- linux 内核 mtd读取,linux内核 mtd分区
- 数据压缩实验八:MPEG音频压缩编码
- kubernetes 是一个分布式的集群管理系统
- python相关库快速下载
- Wolfram 数学习题生成器——AI技术帮你爽到飞