笔记12 注入AspectJ切面
虽然Spring AOP能够满足许多应用的切面需求,但是与AspectJ相比, Spring AOP 是一个功能比较弱的AOP解决方案。AspectJ提供了Spring AOP所不能支持的许多类型的切点。
但是精心设计且有意义的切面很可能依赖其他类来完成它们的工作。 如果在执行通知时,切面依赖于一个或多个类,我们可以在切面内部 实例化这些协作的对象。但更好的方式是,我们可以借助Spring的依 赖注入把bean装配进AspectJ切面中。
我们为演出创建一个新切面。具体来讲,我们以切面的方式创建一个评论员的角色,他会观看演出并且会在演出之后提 供一些批评意见。
在此我们给出完整的代码。首先必须为myeclipse安装AspectJ插件,可以参考:https://blog.csdn.net/qq_35592011/article/details/71602026,安装完成后创建一个AspectJ项目。
1.表演接口Performance.java
package concert4; public interface Performance {
public void perform();
}
2.表演实现类Classcial.java
package concert4; public class Classcial implements Performance { @Override
public void perform() {
// TODO Auto-generated method stub
System.out.println("我是古典音乐会!");
} }
3.观众类(切面)Audience.java
package concert4; import org.aspectj.lang.ProceedingJoinPoint; public class Audience { // ProceedingJoinPoint作为参数。
// 这个对象是必须要有的,因为 你要在通知中通过它来调用被通知的方法。
// 通知方法中可以做任何的 事情,当要将控制权交给被通知的方法时,它需要调 用ProceedingJoinPoint的proceed()方法。
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Silencing cell phone");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP");
} catch (Throwable e) {
System.out.println("Demanding a refund");
}
}
}
4.附加表演接口Encoreable.java
package concert4; public interface Encoreable {
void performEncore();
}
5.附加表演实现类DefaultEncoreable.java
package concert4; public class DefaultEncoreable implements Encoreable { @Override
public void performEncore() {
// TODO Auto-generated method stub
System.out.println("川剧变脸");
} }
6.创建评论切面CriticAspect.java
CriticAspect的主要职责是在表演结束后为表演发表评论。其中的performance()切点匹配perform()方法。当它 与after()returning通知一起配合使用时,我们可以让该切面在 表演结束时起作用。
需要注意的是整个过程并不是评论员自己发表评论,实际 上,CriticAspect与一个CriticismEngine对象相协作,在表 演结束时,调用该对象的getCriticism()方法来发表一个苛刻的 评论。为了避免CriticAspect和CriticismEngine之间产生不 必要的耦合,我们通过Setter依赖注入为CriticAspect设 置CriticismEngine。下图展示了此关系:
package concert4; public aspect CriticAspect {
public CriticAspect(){}
pointcut performance():execution(* perform(..));
after()returning :performance(){
System.out.println("--------------评论----------------");
System.out.println(criticismEngine.getCriticism());
System.out.println("----------------------------------");
} private CriticismEngine criticismEngine; public void setCriticismEngine(CriticismEngine criticismEngine){
this.criticismEngine=criticismEngine;
}
}
7.创建评论员接口CriticismEngine.java
package concert4; public interface CriticismEngine {
public String getCriticism();
}
8.实现评论员接口CriticismEngineTmpl.java(要注入到CriticAspect中的CriticismEngine实现)
package concert4; public class CriticismEngineTmpl implements CriticismEngine { private String[] criticismPool; public void setCriticismPool(String[] criticismPool) {
this.criticismPool = criticismPool;
} public CriticismEngineTmpl() {
} @Override
public String getCriticism() {
// TODO Auto-generated method stub
int i = (int) (Math.random() * criticismPool.length);
return criticismPool[i];
} }
CriticismEngineImpl实现了CriticismEngine接口,通过从 注入的评论池中随机选择一个苛刻的评论。要将这个类在XML文档中声明为一个bean。
9.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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="concert4.Classcial"></bean>
<bean id="audience" class="concert4.Audience"></bean>
<bean id="criticismEngine" class="concert4.CriticismEngineTmpl">
<property name="criticismPool">
<list>
<value>不好</value>
<value>很不好</value>
<value>非常不好</value>
</list>
</property>
</bean>
<bean class="concert4.CriticAspect" factory-method="aspectOf">
<property name="criticismEngine" ref="criticismEngine"></property>
</bean>
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut expression="execution(* concert4.Performance.perform(..))" id="performance"/>
<aop:around method="watchPerformance" pointcut-ref="performance"/>
<aop:declare-parents types-matching="concert4.Performance+"
implement-interface="concert4.Encoreable"
default-impl="concert4.DefaultEncoreable"/>
</aop:aspect>
</aop:config>
</beans>
需要注意的是,在为CriticAspect装配CriticismEngineImple之前,我们必须清楚AspectJ切面根本不需要 Spring就可以织入到我们的应用中。如果想使用Spring的依赖注入为 AspectJ切面注入协作者,那我们就需要在Spring配置中把切面声明为 一个Spring配置中的<bean>。
但是在配置过程中使用了特殊的factorymethod属性。通常情况下,Spring bean由Spring容器初始化,但是 AspectJ切面是由AspectJ在运行期创建的。等到Spring有机会 为CriticAspect注入CriticismEngine时,CriticAspect已 经被实例化了。 因为Spring不能负责创建CriticAspect,那就不能在 Spring中简单 地把CriticAspect声明为一个bean。我们需要一种方式为 Spring获得已经由AspectJ创建的CriticAspect实例的句柄,从而可 以注入CriticismEngine。的AspectJ切面都提供了一 个静态的aspectOf()方法,该方法返回切面的一个单例。所以为了 获得切面的实例,我们必须使用factory-method来调 用asepctOf()方法而不是调用CriticAspect的构造器方法。
简而言之,Spring不能像之前那样使用<bean>声明来创建一 个CriticAspect实例——它已经在运行时由AspectJ创建完成了。 Spring需要通过aspectOf()工厂方法获得切面的引用,然后像 <bean>元素规定的那样在该对象上执行依赖注入。
10.测试类ConcertTest.java
package concert4; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
// @ContextConfiguration(classes = concert3.ConcertConfig.class)
@ContextConfiguration("classpath:ConcertConfig6.xml")
public class ConcertTest {
@Autowired
public Performance p;
@Autowired
public Encoreable en; @Test
public void test() { p.perform();
System.out.println("-----------------------------");
System.out.println("自己创建对象调用");
en.performEncore();
System.out.println("-----------------------------");
System.out.println("通过Performance对象调用“新方法”");
Encoreable e = (Encoreable) p;
e.performEncore();
}
}
11.结果(有疑问!!!!!!!!!!)
笔记12 注入AspectJ切面的更多相关文章
- Spring实战(十二) Spring中注入AspectJ切面
1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...
- 注入AspectJ切面
为什么要用AspectJ:AspectJ提供了Spring AOP很多不能实现的多种切点类型(比如属性,构造方法切入,由于不能实现构造方法的切入spring aop就不能实现对象创建过程的通知) As ...
- Spring AOP实现方式四之注入式AspectJ切面【附源码】
现在我们要讲的是第四种AOP实现之注入式AspectJ切面 通过简单的配置就可以实现AOP了. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.ao ...
- SQL反模式学习笔记12 存储图片或其他多媒体大文件
目标:存储图片或其他多媒体大文件 反模式:图片存储在数据库外的文件系统中,数据库表中存储文件的对应的路径和名称. 缺点: 1.文件不支持Delete操作.使用SQL语句删除一条记录时,对应的文 ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- Spring框架使用(控制反转,依赖注入,面向切面AOP)
参见:http://blog.csdn.net/fei641327936/article/details/52015121 Mybatis: 实现IOC的轻量级的一个Bean的容器 Inversion ...
- Web安全学习笔记 SQL注入上
Web安全学习笔记 SQL注入上 繁枝插云欣 --ICML8 SQL注入分类 SQL注入检测 一.注入分类 1.简介 SQL注入是一种代码注入技术用于攻击数据驱动的应用程序在应用程序中,如果没有做恰当 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...
随机推荐
- 国内maven仓库地址 || 某个pom或者jar找不到的解决方法
解决方法 建议在maven仓库中新建settings.xml,然后把如下内容粘贴进去即可.也可以找到maven的安装目录中的conf/settings.xml,把如下的mirrors节复制到对应部分. ...
- python之路--day13---函数--三元表达式,递归,匿名函数,内置函数-----练习
1.文件内容如下,标题为:姓名,性别,年纪,薪资 egon male 18 3000 alex male 38 30000 wupeiqi female 28 20000 yuanhao female ...
- JAVA_SE基础——15.循环嵌套
嵌套循环是指在一个循环语句的循环体中再定义一个循环语句结构,while,do-while,for循环语句都可以进行嵌套,并且可以互相嵌套,下面来看下for循环中嵌套for循环的例子. 如下: publ ...
- JAVA_SE基础——6.标识符&关键字
学会写helloworld之后, 我们就开始来认识标识符&关键字 一.标识符 标识符是指可被用来为类.变量或方法等命名的字符序列,换言之,标识符就是用户自定义的名称来标识类.变量或方法等.更 ...
- 记录Yii2代码调试中出现的两个问题(截图展示)
1.代码会中断执行,不提示错误信息,是由于substr函数第一个参数为数组造成的 2. 谷歌浏览器调试异步调用接口时出现的错误,需在接口返回处进行断点调试 这两个错误比较隐蔽,调试代码时必须认真仔细
- Autofac 简单示例
公司不用任何IOC,ORM框架,只好自己没事学学. 可能有些语言描述的不专业 希望能有点用 namespace Autofac { class Program { //声明一个容器 private s ...
- 4-51单片机WIFI学习(开发板51单片机自动冷启动下载原理)
上一篇链接 http://www.cnblogs.com/yangfengwu/p/8743936.html 这一篇说一下自己板子的51单片机自动冷启动下载原理,我挥舞着键盘和鼠标,发誓要把世界写个明 ...
- zuul入门(2)zuul的过滤器分类和加载
一.Groovy编写的Filter 1.可以放到指定目录加载 创建一个pre类型的filter,在run方法中获取HttpServletRequest 然后答应header信息 在代码中加入groov ...
- 新概念英语(1-61)A bad cold
新概念英语(1-61)A bad cold What is good news for Jimmy? A:Where's Jimmy? B:He's in bed. A:What's the matt ...
- MySql入门(2-2)创建数据库
mysql -u root -p; show databases; create database apigateway; use apigateway; show tables;