Spring AOP初试
来源:互联网 发布:知柏地黄丸成分 编辑:程序博客网 时间:2024/05/01 21:09
AOP基本概念
切面(Aspect):组织多个通知(增强处理,切面方法,advice)
连接点(Joinpoint):程序执行中明确的点,大概理解成程序执行中的点吧,比如方法执行,异常抛出。Spring AOP中就是方法调用。
通知(增强处理、切面方法、advice):有around、before、after、after returning、after throwing。
切入点(Point Cut):可以插入advice的JoinPoint。当某个连接点满足要求时,该连接点被添加上增强处理。
引入:将方法或字段添加到类中。Spring允许将新的接口引入到任何被处理的类中。
目标对象:被AOP框架进行增强处理的对象。Spring中的AOP代理可以是JDK动态代理(实现接口的目标对象),也可以是cglib代理(不实现接口的目标对象)。
织入(weaving):将增强处理添加到目标对象中,并创建一个被增强对象(AOP 代理)的过程就是织入。织入有两种方式:编译时增强(AspectJ)和运行时增强(如spring AOP)。
使用注解加配置实现
利用IDEA新建web+maven工程
配置信息
web.xml:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value></context-param><listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:annotation-config /> <context:component-scan base-package="com.mitsuhide.*" /> <!--</context:component-scan>--> <aop:aspectj-autoproxy/> <mvc:annotation-driven /></beans>
注意:applicationContext.xml 如果是用maven配置的,一定要放在resource中,否则classpath*或者classpath找不到的。
pom.xml(IDEA的maven实在是好用,最喜欢这点)
加入了(好像aop的只有aop和aspectJ、cglib):
spring-contextspring-webmvcspring-webspring-aopaspectjrtaspectjweaverspring-txspring-aspectscglib-nodep
关键代码
Controller
@Controller@RequestMapping("/mvc")public class HelloController { @RequestMapping("/hello") public @ResponseBody String hello () { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// Athlete zly = (Athlete)context.getBean("Athlete"); Player zly = (Player)context.getBean("Athlete"); return zly.sayHello(); }}
这里有个很有意思的事情,因为Athlete 被绑在切面方法中了,所以获取bean这里需要分情况:
1、Athlete实现了接口
这种情况走的是JDK动态代理,获取bean其实是获取的接口,向上转型了:
Player zly = (Player)context.getBean("Athlete");
2、Athlete一个接口都没实现
这种情况走的是cglib的方式,直接获取类:
Athlete zly = (Athlete)context.getBean("Athlete");
Aspect
@Aspect@Componentpublic class PlayerAspect extends CustomizableTraceInterceptor { @Pointcut("execution( * com.mitsuhide.entity.common.Athlete.*(..))") private void aspectMethod(){}//定义一个切入点 @Before("aspectMethod()") public void before () { System.out.println("方法执行前执行...... By mitsuhide aspect."); } @After("aspectMethod()") public void after () { System.out.println("方法执行后执行...... By mitsuhide aspect."); }}
这里也可以这样写(可以实现接口也可以不实现,因为网上搜的好多教程都是实现了的):
@Before("execution( * com.mitsuhide.entity.common.Athlete.*(..))")
Bean:
@Component("Athlete")public class Athlete implements Player { @Autowired private Basketball ball; public Basketball getBall() { return ball; } public void setBall(Basketball ball) { this.ball = ball; } public String sayHello () { String helloWords = "Hi, I am a " + ball.getBallName() + " player"; return helloWords; } @PostConstruct public void init () { System.out.println("Athlete bean is initializing! By mitsuhide."); } @PreDestroy public void destroy () { System.out.println("Athlete bean is destroying! By mitsuhide."); }}
遇到的问题
1、applicationContext.xml找不到
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
报找不到文件错误,这个是因为maven路径的问题。把xml文件放到resource目录下可解决。
2、切面方法不执行
切面类要同时加上@Aspect,@Component才会执行切面方法。网上教程大多只有·Aspect,我也不造为啥。
3、上面说的需要区分是接口的代理还是类的代理
网上也有另外一种解决办法:
在aop:config标签中添加 proxy-target-class=”true” 即可。
由于生成代理类有两种方式:JDK和CGLIB,一种是基于接口的,一种是基于类的。
如果添加上面的属性则使用基于类的cglib的方式,相反,如果没有写或者是false则通过jdk的基于接口的方式生成代理类。
当然,如果本身不是基于接口的,那么会自动使用cglib的方式,在这里很奇怪为什么没有自动走cglib的方式。
如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。
遗留的问题
spring中context的获取有好几种方式:
ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EntityManager.class);
EntityManager:
@Configuration@ComponentScan(basePackages = {"com.mitsuhide.*"})public class EntityManager {}
@Configuration,@ComponentScan是啥,需要讨论。
- 初试Spring AOP
- Spring AOP初试
- Spring研究之AOP初试
- Spring研究之AOP初试
- java 高新技术【11.2】 动态代理类 编写类似 AOP 与 BeanFactory。初试Spring框架
- java 高新技术【11.2】 动态代理类 编写类似 AOP 与 BeanFactory。初试Spring框架
- Spring Security 初试
- spring mvc+easyui 初试-
- spring data jpa初试
- 初试 spring web mvc
- spring-boot 初试
- 初试Spring MVC
- Spring RestTemplate初试
- AOP、Spring的AOP
- AOP--Spring AOP
- Spring AOP 嵌套AOP
- Spring mvc 第一站 初试
- spring AOP
- 第九周上机实践项目-项目3-工资类
- 【APM】开发环境配置
- 回溯算法之批处理作业调度
- set,bitset 的一个应用实例——数据结构和比较算法
- Java内存模型中的三个代
- Spring AOP初试
- 2016SDAU编程练习二1016
- 归并排序
- Java永久代去哪儿了
- nrf51822 --- 内部温度传感器
- 线性反馈移位寄存器的实现
- 【bzoj4066】【简单题】【kd树】
- 百度地图之定位
- 搜索专题总结