Spring基础入门AOP
2017-11-19 13:09
405 查看
AOP简介
1.什么是AOP ? 它有什么用?AOP(Aspect Oriented Programming,面向切面编程), 可以说是OOP(Object Oriented Programing,面向对象编程)的补充和完善。在不改动源码的前提下,对原有的功能进行扩展 | 升级
2.AOP的底层原理是什么?
在JAVA的世界里,能够不改代码而又能进行扩展代码的,不多,常见的有装饰者模式,代理模式(静态代理,动态代理),而AOP的底层使用的是动态代理,因为使用静态代理 | 装饰者模式 需要提供一个实实在在类,而使用动态代理,只需要一个被装饰对象,或对象字节码对象即可
3.代理回顾,静态代理方式
3.代理回顾,动态代理实现方式
画的有点丑,别介意
4.基于JDK方式代码
//创建一个接口 JDK方式需要实现接口,如果类没有实现接口,那么只能使用cglib方式 public interface A { void run(); void eat(); }
//创建一个实体类 实现接口 public class People implemts A{ public void eat(){ System.out.println("吃"); } public void run(){ System.out.println("跑"); } }
public class Jdk { @Test public void Test_01(){ A people = new People(); //创建实体类对象 // 使用动态代理 Class clazz = people.getClass(); //Proxy.newProxyInstance()需要的参数 //1.类加载器 2.目标类实现的接口,也就是People实现的接口 3.一个new InvocationHandler()的回调函数 //获取代理对象 A a = (A) Proxy.newProxyInstance(this.getClass().getClassLoader(), clazz.getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //加强睡的方法 if ("eat".equals(method.getName())) { System.out.println("加餐啦!"); } return method.invoke(people,args); } }); proxy.eat(); } }
运行结果如下
5.基于Cglib方式代码
主要针对没有实现接口的类,底层通过创建另一个子类作为代理类
//创建一个目标类,不实现接口 public class Anli { public void eat(){ System.out.println("开始吃"); } public void run(){ System.out.println("开始跑"); } }
创建一个测试类
public class Cglib { @Test public void Test_01(){ //创建目标类的真实对象, final Anli anli = new Anli(); //创建一个代理对象 Enhancer enhancer = new Enhancer(); //这不是代理对象,是创建代理对象的模板,可以理解为代理对象工厂 enhancer.setSuperclass(anli.getClass()); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //加强吃的方法 if ("eat".equals(method.getName())) { System.out.println("再一次加餐啦"); } return method.invoke(anli,objects); } }); //创建代理类 Anli a = (Anli)enhancer.create(); a.eat(); } }
运行结果如下
总结 : 被代理类如果实现了接口就使用JDK的方式,如果没有实现,就是用Cglib方式,开发中通常会使用JDK的方式,开发中都是使用接口来定义规范的.
6.回归正题,我们开始讲AOP
讲AOP之前,我们需要了解AOP的术语,连接点
切入点
切面
话不多说,直接上图
了解完AOP术语,那么我们就开始实际操作
1.导入spring需要的jar包,和日志包(如果没有的话,可以在我上传资源里面下载,注意,jar包只用导入一部分)导入jar包如下
五个核心jar包
spr
4000
ing-beans-xxx.jar
spring-context-xxx.jar
spring-context.xxx.jar
spring-core-xxx.jar
spring-expression-xxx.jar
日志jar包
jcl-over-slf4j-xxx.jar
log4j-xxx.jar
slf44j-api-xxx.jar
slf4j-log4j-xxx.jar
需要注意的是,导入日志jar包后,需要提供一个log4j.properties文件
导入aop需要的jar包
spring-aop-xxx.jar
spring-aspects-xxx.jar
面向切面过程中Spring AOP是遵循AOP联盟规范实现的,所以需要AOP联盟的接口包
aoplliance-xx.jar
接口包依赖aspectJweaver-xxx.jar
如果没有jar包的话,可以在我的资源里面找
log4j.properties文件内容如下
##\u8BBE\u7F6E\u65E5\u5FD7\u8BB0\u5F55\u5230\u63A7\u5236\u53F0\u7684\u65B9\u5F0F log4j.appender.s=org.apache.log4j.ConsoleAppender log4j.appender.s.Target=System.err log4j.appender.s.layout=org.apache.log4j.PatternLayout log4j.appender.s.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n ##\u8BBE\u7F6E\u65E5\u5FD7\u8BB0\u5F55\u5230\u6587\u4EF6\u7684\u65B9\u5F0F log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n ##\u65E5\u5FD7\u8F93\u51FA\u7684\u7EA7\u522B\uFF0C\u4EE5\u53CA\u914D\u7F6E\u8BB0\u5F55\u65B9\u6848 log4j.rootLogger=info, s, file
2.导入applicationContext.xml配置所需要的约束 (aop约束)
spring-framework-4.2.9.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html里面搜索aop就行
spring-framework-4.2.9.RELEASE是在spring官网下载的文件夹名
html索搜快捷键 ctrl+shift +f
复制约束,粘贴到xml即可
3.编写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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="Pipixia" class="cn.itcast.aop.Pipixia"/> <bean id="People" class="cn.itcast.aop.People"/> <aop:config > <!-- 切入点 到底哪些方法要被扩展 execution(* com.xyz.myapp.service..(..)) execution: 固定写法 第一个* : 任意返回值 com.xyz.myapp.service : 具体包 第二个* : 包下的所有类 第三个* : 类中的所有方法 (..) : 方法的任意参数 --> <!--创建一个切入点--> <aop:pointcut id="point" expression="execution(* cn.itcast.aop.Pipixia.*(..))"/> <!--创建一个切面 ,ref是提供扩展方法的类--> <aop:aspect ref="People"> <!--提供People类的eat方法,before是增强位置--> <aop:before method="eat" pointcut-ref="point" /> </aop:aspect> </aop:config> </beans>
AOP增加介绍
<aop:config> <!-- us === saveUser ps === saveProduct os ===saveOrder --> <aop:pointcut expression="execution(* com.itcast.*.*.eat*(..))" id="aa"/> <aop:aspect ref="People"> <!-- 前置增强,People类eat方法会在执行itcast包下所有类的方法前执行,只要是itcast包下的方法,执行前都会执行一遍People的方法,出异常不知晓 --> <!-- <aop:before method="eat" pointcut-ref="aa" /> --> <!-- 最终增强 不管有没有异常都执行--> <!-- <aop:after method="eat" pointcut-ref="aa" /> --> <!-- 环绕增强 --> <!-- <aop:before method="eat" pointcut-ref="aa" /> <aop:after method="eat" pointcut-ref="aa" /> --> <!--环绕增强,被增强方法执行前后都是执行eat方法,不过需要额外配置--> <!-- <aop:around method="around" pointcut-ref="aa"/> --> <!-- 后置增强,被增强方法执行完后会执行一遍 People类的eat方法--> <!-- <aop:after-returning method="eat" pointcut-ref="aa"/> --> <!-- 异常增强,被增强方法出了异常才会增强执行eat方法 --> <aop:after-throwing method="eat" pointcut-ref="aa"/> </aop:aspect> </aop:config>
由于时间问题,就不演示了
就值演示一个before前置增强
编写一个测试类
//使用spring提供的测试方法,使用需要导入test的jar包 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo_02 { @Resource private Pipixia p; @Test public void demo_01(){ p.eat(); } }
执行结果如下
它先执行了People的eat方法,
然后再执行了Pipixia的eat方法
以上就是AOP简单入门,下次我们会讲IOC,DI注解写法,有问题评论留言
相关文章推荐
- spring 学习(1.3) 入门基础- AOP 实例
- Spring AOP @AspectJ 入门基础
- spring 学习(1.4) 入门基础- AOP教程
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
- Spring基础入门之Ioc、DI、AOP
- [Spring框架]Spring AOP基础入门总结一.
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
- 0047 Spring的AOP入门基础--切面组件--通知--切入点
- [Spring框架]Spring AOP基础入门总结一.
- JavaEE框架——Spring入门基础(控制反转Ioc和切面技术Aop)
- Spring -- AOP入门基础&基于Aspect的AOP通知用法
- spring 学习(1.2) 入门基础- AOP
- Spring入门AOP(一)
- SpringAOP使用入门,如何对自定义的注解进行切面编程
- Spring Boot入门3——AOP处理请求
- Spring Boot 入门之基础篇(一)
- Spring aop(Aspect Oriented Programming:面向切面编程)入门
- Spring入门6---AOP1
- Spring基础:快速入门spring(8):bean scope
- spring 入门实战(四) Aop