目录

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 学习设计模式的意义:

  1. 设计模式的本质是面向对象设计原则的实际运用, 是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。
  2. 正确使用设计模式具有以下优点:
  3. 可以提高程序员的思维能力、编程能力和设计能力。
  4. 使程序设计更加标准化、 代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
  5. 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。
  6. 个人总结 增强自己编码的思维能力,以另外的一种思维解决生活中的问题。

3 GoF23设计模式指哪些:每种模式体现每一种解决问题的思想能力

  1. ◆创建型模式:
  2. ◆单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。
  3. ◆结构型模式:
  4. ◆适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式◆行为型模式:
  5. ◆模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式。

4  0PG七大原则      

  1. ◆开闭原则:对扩展开放,对修改关闭
  2. ◆里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立
  3. ◆依赖倒置原则:要面向接口编程,不要面向实现编程。
  4. ◆单一职责原则:控制类的粒度大小、将对象解耦、 提高其内聚性。
  5. ◆接口隔离原则:要为各个类建立它们需要的专用接口
  6. ◆迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。
  7. ◆合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

5 Java的23设计模式的以下的内容大概介绍:      

1 创建型模式

  1. 创建型模式 对象实例化的模式,创建型模式用于解耦对象的实例化过程。
  2. 单例模式:某个类智能有一个实例,提供一个全局的访问点。
  3. 工厂模式:一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
  4. 抽象工厂模式:创建相关或依赖对象的家族,而无需明确指定具体类。
  5. 建造者模式:封装一个复杂对象的创建过程,并可以按步骤构造。
  6. 原型模式:通过复制现有的实例来创建新的实例。

 2 结构型模式:把类或对象结合在一起形成一个更大的结构。

  1. 装饰器模式:动态的给对象添加新的功能。
  2. 代理模式:为其它对象提供一个代理以便控制这个对象的访问。
  3. 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
  4. 适配器模式:将一个类的方法接口转换成客户希望的另一个接口。
  5. 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
  6. 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
  7. 享元模式:通过共享技术来有效的支持大量细粒度的对象。

 3 行为型模式:类和对象如何交互,及划分责任和算法。

  1. 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
  2. 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
  3. 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
  4. 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。
  5. 观察者模式:对象间的一对多的依赖关系。
  6. 仲裁者模式:用一个中介对象来封装一系列的对象交互。
  7. 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
  8. 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
  9. 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
  10. 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
  11. 访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。

第二部分 代理模式:为其它对象提供一个代理以便控制这个对象的访问 进入静态代理模式的学习 这里会用两个案例来讲述什么是 代理模式 这里的每种模式是一种思维 要读者去理解其思维的能力

代理模式的好处:

●可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务●公共也就就交给代理角色!实现了业务的分工!

●公共业务发生扩展的时候,方便集中管理!

缺点:

●一个真实角色就会产生-个代理角色;代码量会翻倍~开发效率会变低~

下面用几张图来理解什么是代理模式哦

案例一

案例二

角色分析


案例一  抽象角色一般是接口或者是实现类 中介

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动态代理 四种方式

案例三:

  1. JDK动态代理:运行期动态的创建代理类,只支持接口。

  2. ASM:一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解;cglib基于ASM实现动态代理。

  3. javassist:一个开源的分析、编辑和创建Java字节码的类库(源码级别的类库)。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类;

  4. bytebuddy:一个更高层次操作字节码的工具包。

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+"方法");}}

案例四的运行结果

动态代理的总结:

动态代理和静态代理角色- -样

●动态代理的代理类是动态生成的,不是我们直接写好的!

●动态代理分为两大类:基于接口的动态代理 ,基于类的动态代理。基于接口-- JDK动态代理[我们在这里使用]

) 基于类: glib

java字节码实现: javasist

需要了解两个类: Proxy: 代理,InvocationHandler:

第三部分 Spring框架中的Aop@理解Aop的基础概念@了解Aop开发的三种方式 备注Spring框架的学习基于了解Maven项目的前提下开始的哦!

提供声明式事务;允许用户自定义切面==

●横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等....

●切面(ASPECT) :横切关注点被模块化的特殊对象。即,它是一个类。

●通知(Advice) :切面必须要完成的工作。即,它是类中的一-个方法。

●目标(Target) :被通知对象。

●代理(Proxy) :向目标对象应用通知之后创建的对象。

●切入点(PointCut) :切面通知执行的“地点”的定义。

●连接点(JointPoint) :与切入点匹配的执行点。


项目的结构


<?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的学习相关推荐

  1. 爬虫入门学习(七)IP学习与代理池构建

    爬虫入门学习(七)IP学习与代理池构建 1 IP简介 2 IP被封的原因 3 应对IP被封的策略 3.1 伪造User-Agent 3.2 设置线程等待sleep() 3.3 伪造Cookies 3. ...

  2. [学习笔记] python深度学习---第七章 深度学习最佳实践

    一.联合学习 如果只有元数据,那么可以使用one-hot编码,然后用密集连接网络来预测价格.如果只有文本描述,那么可以使用循环神经网络或一维卷积神经网络.如果只有图像,那么可以使用二维卷积神经网络.但 ...

  3. jQuery框架学习第七天:jQuery动画–jQuery让页面动起来!

    jQuery框架学习第一天:开始认识jQuery jQuery框架学习第二天:jQuery中万能的选择器 jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQu ...

  4. Java IO流学习总结七:Commons IO 2.5-FileUtils

    Java IO流学习总结七:Commons IO 2.5-FileUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/5497 ...

  5. Java回炉学习(七)

    Java回炉学习(七) 1. 泛型 泛型的好处:1. 编译时,检查添加元素的类型,提高了安全性 2. 减少了类型转换的次数,提高效率 //泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型 ...

  6. ESP32学习笔记(七) 复位和时钟

    ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...

  7. 大数据学习系列:Hadoop3.0苦命学习(七)

    传送门: 大数据学习系列:Hadoop3.0苦命学习(一) 大数据学习系列:Hadoop3.0苦命学习(二) 大数据学习系列:Hadoop3.0苦命学习(三) 大数据学习系列:Hadoop3.0苦命学 ...

  8. 李弘毅机器学习笔记:第七章—深度学习的发展趋势

    李弘毅机器学习笔记:第七章-深度学习的发展趋势 回顾一下deep learning的历史: 1958: Perceptron (linear model) 1969: Perceptron has l ...

  9. 第七周编程学习笔记(4.17-4.23)

    目录 第一天4.17  星期一   anaconda环境配置     深度学习基础 第二天4.18  星期二  AI软件.sketchup.数据库与数据结构 第三天4.19  星期三  论文表格和图片 ...

最新文章

  1. 乐观锁与悲观锁——解决并发问题
  2. 学以致用一:得到数组的最后一个元素。
  3. 最高5000倍加速模拟物理世界,育碧在修复bug上又进一步
  4. Hibernate实现limit查询报错 unexpected token: ? near line 1, column 30 [from cn.com.bean.Layer limit ? ,
  5. Node.js HTTPS
  6. java开发爱恩斯坦棋,爱恩斯坦棋计算机博弈关键技术研究
  7. Linux Load Balancing之NAT与DR模型
  8. 开源Easydarwin流媒体服务器Windows编译、配置、部署
  9. 门槛低的行业看天赋,门槛高的行业看毅力
  10. C++数据类型之结构体的练习(用到结构体的赋值,利用结构体元素排序以及查找)
  11. 【渝粤教育】国家开放大学2018年秋季 0463-21T英语语音 参考试题
  12. 会计计算机学什么软件有哪些,会计学习软件
  13. 酷客数据python基础实战答案_英语听力练习_日语_韩语_法语听力训练网站-沪江听力酷...
  14. [软件安装] 动态图像录制工具LICEcap
  15. 高级驾驶辅助系统ADAS简介
  16. linux 内核 mtd读取,linux内核 mtd分区
  17. 数据压缩实验八:MPEG音频压缩编码
  18. kubernetes 是一个分布式的集群管理系统
  19. python相关库快速下载
  20. Wolfram 数学习题生成器——AI技术帮你爽到飞

热门文章

  1. 全国教育专业学位研究生教指委函件
  2. 如何学习新概念英语2
  3. PHPWeb开发相关知识
  4. 记录我的大疆无人机消费体验
  5. Flink——有界流VS无界流
  6. 环网柜开关柜开闭所局部放电在线监测装置/MCSG-PD-6016空间超高频局放在线监测装置系统在10kV开关柜中的应用
  7. 会声会影2022正式版一键式视频剪辑软件
  8. 【python练习】打印菱形
  9. win7优化大师_Win7设置某个用户自动登录的方法
  10. Android自带组件之Gallery 实现3D画廊效果