虽然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切面的更多相关文章

  1. Spring实战(十二) Spring中注入AspectJ切面

    1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...

  2. 注入AspectJ切面

    为什么要用AspectJ:AspectJ提供了Spring AOP很多不能实现的多种切点类型(比如属性,构造方法切入,由于不能实现构造方法的切入spring aop就不能实现对象创建过程的通知) As ...

  3. Spring AOP实现方式四之注入式AspectJ切面【附源码】

    现在我们要讲的是第四种AOP实现之注入式AspectJ切面 通过简单的配置就可以实现AOP了. 源码结构: 1.首先我们新建一个接口,love 谈恋爱接口. package com.spring.ao ...

  4. SQL反模式学习笔记12 存储图片或其他多媒体大文件

    目标:存储图片或其他多媒体大文件 反模式:图片存储在数据库外的文件系统中,数据库表中存储文件的对应的路径和名称. 缺点:     1.文件不支持Delete操作.使用SQL语句删除一条记录时,对应的文 ...

  5. Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建

    Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...

  6. Spring框架使用(控制反转,依赖注入,面向切面AOP)

    参见:http://blog.csdn.net/fei641327936/article/details/52015121 Mybatis: 实现IOC的轻量级的一个Bean的容器 Inversion ...

  7. Web安全学习笔记 SQL注入上

    Web安全学习笔记 SQL注入上 繁枝插云欣 --ICML8 SQL注入分类 SQL注入检测 一.注入分类 1.简介 SQL注入是一种代码注入技术用于攻击数据驱动的应用程序在应用程序中,如果没有做恰当 ...

  8. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  9. 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...

随机推荐

  1. 命令行窗口中用telnet测试HTTP协议

    1. 命令行窗口中用telnet测试HTTP协议 HTTP消息是由普通ASCII文本组成.消息包括消息头和数据体部分.消息头以行为单位,每行以CRLF(回车和换行)结束,消息头结束后,额外增加一个CR ...

  2. Xen Server虚拟机数据恢复的方法和数据恢复过程

    在服务器运行过程中如果出现意外情况突然断电很容易引起服务器故障,服务器中的硬件设备损坏可以修复或者购买,但是服务器中的数据一旦发生故障丢失,对于企业来说将是不可估量的损失.那么服务器数据一旦丢失就除了 ...

  3. JAVA_SE基础——22.面向对象的概念

    我写博客是为了提升自己和为了进入黑马程序员学习,还有分享些自己的心得给大家,希望能帮助大家学习JAVA. 我是自学的,如果写的有错误或者能更好的修改的请提出. 在这里我先引用下<think in ...

  4. 剑指offer-数组中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  5. WPF 自定义TextBox带水印控件,可设置圆角

    一.简单设置水印TextBox控件,废话不多说看代码: <TextBox TextWrapping="Wrap" Margin="10" Height=& ...

  6. greenplum集群某台机器磁盘占用100%处理方式

    一.问题描述 使用gpfdist往集群中导入大量数据, 一段时间后连接退出,集群无法连接 二.问题定位 使用如下命令查看: gpstate -s mdw-:gpadmin-[INFO]:- Segme ...

  7. SSM登陆注册

    package com.coingod.controller; import java.io.IOException;import java.io.PrintWriter;import java.ut ...

  8. scrollTop doesn't scroll on Chrome 61

    在chrome61 不支持滚动 解决方案: Use document.scrollingElement if supported, and fall back to the current code. ...

  9. 1.1 WEB API 在帮助文档页面进行测试

    这篇文章http://www.cnblogs.com/landeanfen/p/5210356.html写得比较详细, 我就挑简单的来说. 首先用这功能要在WEB API创建的帮助文档下面,如果你使用 ...

  10. requests-文件上传

    import requests files = {'file':open('D://tomas.jpg','rb')}#设定一个files,打开文件对象 response = requests.pos ...