8.AOP全自动
CGLIB字节码增强
l没有接口,只有实现类。
采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。
导入jar包:
自己导包(了解):
核心:hibernate-distribution-3.6.10.Final\lib\bytecode\cglib\cglib-2.2.jar
依赖:struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib\asm-3.3.jar
spring-core..jar 已经整合以上两个内容
目标类
UserServiceImpl.java
package com.jd.proxy.cglib; public class UserServiceImpl { public void addUser() {
System.out.println("a_proxy.b_cglib addUser");
} public void updateUser() {
System.out.println("a_proxy.b_cglib updateUser"); } public void deleteUser() { System.out.println("a_proxy.b_cglib deleteUser");
} }
切面类
MyAspect
package com.jd.proxy.cglib; public class MyAspect { public void before(){
System.out.println("鸡首2");
} public void after(){
System.out.println("牛后2");
} }
工厂类
MyBeanFactory.java
package com.jd.proxy.cglib; import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /**
* @author weihu
* @date 2018/8/16/016 23:48
*/
public class MyBeanFactory { public static UserServiceImpl createService() {
//1.目标类
UserServiceImpl userService = new UserServiceImpl();
//2.切面类
MyAspect myAspect = new MyAspect();
// 3.代理类 ,采用cglib,底层创建目标类的子类
//3.1 核心类
Enhancer enhancer = new Enhancer();
//3.2 确定父类
enhancer.setSuperclass(userService.getClass());
/* 3.3 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHandler接口
* intercept() 等效 jdk invoke()
* 参数1、参数2、参数3:以invoke一样
* 参数4:methodProxy 方法的代理
*
*
*/
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//前
myAspect.before(); //执行目标类的方法
Object obj = method.invoke(userService, objects);
// * 执行代理类的父类 ,执行目标类 (目标类和代理类 父子关系)
// methodProxy.invokeSuper(o,objects); //后
myAspect.after();
return obj;
}
});
UserServiceImpl proxService = (UserServiceImpl) enhancer.create();
return proxService;
}
}
测试
TestCglib.java
package com.jd.proxy.cglib; import org.junit.Test; /**
* @author weihu
* @date 2018/8/16/016 23:55
*/
public class TestCglib { @Test
public void testCglib(){
UserServiceImpl service = MyBeanFactory.createService();
service.addUser();
service.updateUser();
service.deleteUser();
}
}
AOP联盟通知类型
l AOP联盟为通知Advice定义了org.aopalliance.aop.Advice l Spring按照通知Advice在目标类方法的连接点位置,可以分为5类 前置通知 org.springframework.aop.MethodBeforeAdvice
在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice
在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor
在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice
在方法抛出异常后实施增强
引介通知 org.springframework.aop.IntroductionInterceptor
在目标类中添加一些新的方法和属性
环绕通知,必须手动执行目标方法 try{ //前置通知 //执行目标方法 //后置通知 } catch(){ //抛出异常通知 }
spring编写代理:半自动
让spring 创建代理对象,从spring容器中手动的获取代理对象。
导入jar包:
核心:4+1
AOP:AOP联盟(规范)、spring-aop (实现)
目标类
UserService.java
package com.jd.proxy.factorybean; public interface UserService { public void addUser();
public void updateUser();
public void deleteUser(); }
切面类
MyAspect.java
package com.jd.proxy.factorybean; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; /**
* 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
* 采用“环绕通知” MethodInterceptor
*/
public class MyAspect implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("前"); //手动执行目标方法
Object obj = methodInvocation.proceed(); System.out.println("后");
return obj;
}
}
UserServiceImpl.java
package com.jd.proxy.factorybean; public class UserServiceImpl implements UserService { @Override
public void addUser() {
System.out.println("b_factory_bean addUser");
} @Override
public void updateUser() {
System.out.println("b_factory_bean updateUser"); } @Override
public void deleteUser() { System.out.println("b_factory_bean deleteUser");
} }
spring配置
beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 创建目标类 -->
<bean id="userServiceId" class="com.jd.proxy.factorybean.UserServiceImpl"></bean>
<!-- 创建切面类 -->
<bean id="myAspectId" class="com.jd.proxy.factorybean.MyAspect"></bean> <!-- 创建代理类
* 使用工厂bean FactoryBean ,底层调用 getObject() 返回特殊bean
* ProxyFactoryBean 用于创建代理工厂bean,生成特殊代理对象
interfaces : 确定接口们
通过<array>可以设置多个值
只有一个值时,value=""
target : 确定目标类
interceptorNames : 通知 切面类的名称,类型String[],如果设置一个值 value=""
optimize :强制使用cglib
<property name="optimize" value="true"></property>
底层机制
如果目标类有接口,采用jdk动态代理
如果没有接口,采用cglib 字节码增强
如果声明 optimize = true ,无论是否有接口,都采用cglib -->
<bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.jd.proxy.factorybean.UserService"></property>
<property name="target" ref="userServiceId"></property>
<property name="interceptorNames" value="myAspectId"></property>
</bean>
</beans>
测试
TestFactoryBean.java
package com.jd.proxy.factorybean; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author weihu
* @date 2018/8/18/018 18:11
*/
public class TestFactoryBean { @Test
public void testAop(){
String xmlPath="com/jd/proxy/factorybean/beans.xml"; //获得代理类
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("proxyServiceId");
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
}
spring aop编程:全自动【掌握】
从spring容器获得目标类,如果配置aop,spring将自动生成代理。
要确定目标类,aspectj 切入点表达式,导入jar包
spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE
spring配置
beans.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="userServiceId" class="com.jd.proxy.aop.UserServiceImpl"></bean>
<!-- 创建切面类(通知) -->
<bean id="myAspectId" class="com.jd.proxy.aop.MyAspect"></bean>
<!-- aop编程
3.1 导入命名空间
3.2 使用 <aop:config>进行配置
proxy-target-class="true" 声明时使用cglib代理
<aop:pointcut> 切入点 ,从目标对象获得具体方法
<aop:advisor> 特殊的切面,只有一个通知 和 一个切入点
advice-ref 通知引用
pointcut-ref 切入点引用
3.3 切入点表达式
execution(* com.itheima.c_spring_aop.*.*(..))
选择方法 返回值任意 包 类名任意 方法名任意 参数任意 -->
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(* com.itheima.c_spring_aop.*.*(..))" id="myPointCut"/>
<aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/>
</aop:config>
</beans>
MyAspect.java
package com.jd.proxy.aop; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; /**
* 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。
* * 采用“环绕通知” MethodInterceptor
*
*/
public class MyAspect implements MethodInterceptor { @Override
public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("前4"); //手动执行目标方法
Object obj = mi.proceed(); System.out.println("后4");
return obj;
}
}
UserService.java
package com.jd.proxy.aop; public interface UserService { public void addUser();
public void updateUser();
public void deleteUser(); }
UserServiceImpl.java
package com.jd.proxy.aop; public class UserServiceImpl implements UserService { @Override
public void addUser() {
System.out.println("c_spring_aop addUser");
} @Override
public void updateUser() {
System.out.println("c_spring_aop updateUser"); } @Override
public void deleteUser() { System.out.println("c_spring_aop deleteUser");
} }
TestSpringAOP.java
package com.jd.proxy.aop; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author weihu
* @date 2018/8/18/018 18:21
*/
public class TestSpringAOP { @Test
public void testAop(){
String xmlPath="com/jd/proxy/aop/beans.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath); //获得目标类
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
}
8.AOP全自动的更多相关文章
- Spring全自动AOP和项目加入jar包
一.jar可以引进项目中,复制到路下后,要add as library,加载到工作空间中才能引入: 也jar包放在硬盘的项目目录外面,可以多个项目引入共用: 二.xml配置 1.aop全自动配置 2. ...
- Spring框架的基本使用(AOP部分)
AOP,Aspect Oriented Programming,意为面向切面编程,是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP采取横向抽取机制,取代了传统纵向继承体系重复 ...
- Spring常用配置
----------------------------------------------------------------------------------------------[版权申明: ...
- AOP 手动,半自动,全自动
dao层 package com.yaorange.dao; public interface StudentDao { public void saveStudent(); public void ...
- spring的aop编程(半自动、全自动)
1.spring的半自动代理(从spring中获取代理对象) (1)spring中的通知类型 spring中aop的通知类型有五种: 前置:在目标方法执行前实施加强 后置:在目标方法执行后实施加强 环 ...
- spring(二) AOP之AspectJ框架的使用
前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...
- Spring框架-AOP详细学习[转载]
参考博客:https://blog.csdn.net/qq_22583741/article/details/79589910#4-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85% ...
- spring学习(二) ———— AOP之AspectJ框架的使用
前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...
- AOP切面编程
1.JDK动态代理方式实现 public static UserService createService(){ //目标类 final UserService userService = new U ...
随机推荐
- 63.(原65)纯 CSS 创作一个摇摇晃晃的 loader
原文地址:https://segmentfault.com/a/1190000015424389 修改后地址:https://scrimba.com/c/cqKv4VCR HTML code: < ...
- 注解_Annotation
---恢复内容开始--- 一.什么是注解 注解,英文Annotation,它不是程序本身,是对程序的解释,在这里我会想到为什么不能使用注释呢,因为注解是关于程序对信息的处理的流程的一些说明,而且格式也 ...
- Web请求过程
一.Http解析 Http Header控制着成千上万的互联网用户的数据传输,控制着用户浏览器的渲染行为和服务器的执行逻辑. HTTP请求头 Accept-Language: zh-cn,zh;q=0 ...
- Node.js 程序应用
在打开cmd 控制台 输入 node 然后在cmd中 输入您想要的代码 加减乘除 算法.
- 分布式版本控制系统Git的安装和使用
作业要求来自https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2097 GitHub远程仓库的地址:https://github.com/ ...
- 图片的滑动缩放html、css、js代码
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- oralce 中union 和union all 的简单使用说明
union:对两个结果集进行合并操作:不包括重复行:同时进行默认规则的排序: union all:对两个结果集进行合并操作:包括重复行:不排序:
- SpringBoot的spring-boot-starter有哪些(官方)
看完这些,你就知道每个spring-boot-starter依赖些什么东西了. 地址:https://github.com/spring-projects/spring-boot/tree/v2.1. ...
- CF 225C Barcode(DP)
传送门:点我 You've got an n × m pixel picture. Each pixel can be white or black. Your task is to change t ...
- PTA 1067 Sort with Swap(0, i) (25 分)(思维)
传送门:点我 Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasin ...