spring框架应用系列三:切面编程(带参数)
切面编程(带参数)
本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7786715.html
解决问题
1、分离业务监控与业务处理。简单点说,让开发人员更专注业务逻辑开发,类似于打印日志、统计时间、监控等等独立成一个单独的类,在需要的时候,动态的将代码切入到类的指定方法上,使方法拥有更强大的功能;
2、解决代码重复性,降低代码复杂程度;
内容说明
1、通过@Component注解,扫描(Magician)bean并注册到spring容器中时,需在XML配置文件中引入 <context:component-scan base-package="com.spring.example.aspectArgs"/>;
2、明确切面、切点、通知概念,这里切面是Magician,切点是Volunteer的thinkOfSomething方法,通知是Magician中所包含方法,由xml或注解配置,下面会分别给出示例;
3、通过执行Volunteer的thinkOfSomething方法,从而执行Magician中相应的方法,达到通知的效果;
应用实例:截听志愿者内心真实想法
先列出相关接口以及类代码
切面实现接口MindReader(读心者)
package com.spring.example.aspectAspectJArgs;
//读心者
public interface MindReader {
void interceptThoughts(String thoughts);
void getConclusion(String thoughts);
}
切点类志愿者实现接口Thinker
package com.spring.example.aspectAspectJArgs;
/**
* 读心者赋予一个他需要截听内心感应的志愿者
*/
public interface Thinker {
void thinkOfSomething(String thoughts);
}
志愿者实体类Volunteer
package com.spring.example.aspectAspectJArgs;
import org.springframework.stereotype.Component;
/**
* Created by weixw on 2017/10/24.
*/
@Component
public class Volunteer implements Thinker {
private String thoughts;
@Override
public void thinkOfSomething(String thoughts) {
this.thoughts = thoughts;
}
}
以下有两种方式实现此实例的切面编程:一、通过XML配置文件,二、AspectJ注解方式
其他代码都相同,不同处在spring 的xml配置文件以及切面类文件
一、通过XML配置文件:
切面(读心者)实体类
package com.spring.example.aspectArgs;
/**
* Created by weixw on 2017/10/24.
*/
import org.springframework.stereotype.Component;
/**
* 截听志愿者的内心感应和显示他们在想什么
*/
@Component
public class Magician implements MindReader {
@Override
public void interceptThoughts(String thoughts) {
System.out.println("Intercepting volunteer's thoughts :" +thoughts);
}
@Override
public void getConclusion(String thoughts) {
System.out.println("For your thoughts :" +thoughts);
System.out.println("I think you are right.");
}
}
spring 配置文件 aspect-args.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"
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">
<context:component-scan base-package="com.spring.example.aspectArgs"/>
<aop:config>
<!--通过component-scan自动扫描,@Component注解将Magician注册到spring容器-->
<aop:aspect ref="magician">
<aop:pointcut id="thinking" expression="execution(*
com.spring.example.aspectArgs.Thinker.thinkOfSomething(String))
and args(thoughts)"/>
<aop:before pointcut-ref="thinking" method="interceptThoughts" arg-names="thoughts"/>
<aop:after pointcut-ref="thinking" method="getConclusion" arg-names="thoughts"/>
</aop:aspect>
</aop:config>
</beans>
二 、AspectJ注解方式
切面(读心者)实体类
package com.spring.example.aspectAspectJArgs;
/**
* Created by weixw on 2017/10/24.
*/
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 截听志愿者的内心感应和显示他们在想什么
*/
@Component
@Aspect
public class Magician implements MindReader {
@Pointcut("execution(* com.spring.example.aspectAspectJArgs.Thinker.thinkOfSomething(String)) " +
"&& args(thoughts)") //定义切点
public void thinkOfSomething(String thoughts){}
@Before("thinkOfSomething(thoughts)")
@Override
public void interceptThoughts(String thoughts) {
System.out.println("Intercepting volunteer's thoughts :" +thoughts);
}
@AfterReturning("thinkOfSomething(thoughts)")
@Override
public void getConclusion(String thoughts) {
System.out.println("For your thoughts :" +thoughts);
System.out.println("I think you are right.");
}
}
spring 配置文件 aspect-aspectJArgs.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"
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">
<context:component-scan base-package="com.spring.example.aspectAspectJArgs"/>
<aop:aspectj-autoproxy/>
</beans>
测试代码
注解测试代码如下,配置文件测试代码只需将配置文件名称改成spring/aspect-args.xml即可
package com.spring.example.aspectAspectJArgs;/**
* Created by weixw on 2017/10/19.
*/
import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Driver extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/aspect-aspectJArgs.xml");
Thinker thinker = (Thinker) ctx.getBean("volunteer");
thinker.thinkOfSomething("I'm stupid.");
}catch (Exception e){
e.printStackTrace();
}
}
}
运行结果
总结
上述列出配置文件和注解两种方式都能实现切面编程。但对于自身业务开发,个人觉得注解方式较好,因为在修改某一切面类时不需要多处修改;
本文描述可能有不对或不全之处,欢迎大家吐槽!
不要让懒惰占据你的大脑,不要让妥协拖垮你的人生。青春就是一张票,能不能赶上时代的快车,你的步伐掌握在你的脚下。
- 熊普江: BGP网络架构助力开发者快速构建、优化业务
- 唐良:云端架构给电商行业带来创新力
- 邹方明:看腾讯云如何架构海量存储系统
- 王之捷:AI智能云端架构大幅提升智能语音识别能力
- 精彩大放送 | 腾讯云:容器架构向无服务架构的演进
- Python 数据分析学习笔记
- 如何用Fiddler抓取https
- 人工智能与大数据结合,帮助降低自杀率
- “多态”的数据库连接池实现
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider
- 用js代码理解区块链,最简版本
- 谈谈IE针对Ajax请求结果的缓存
- Ajax请求过程中显示“进度”的简单实现
- ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释