众所周知,JavaSpring的两大突出优势是IOC(控制反转)和AOP(面向切面编程)。
我也是最近这几天才开始学习这个框架,有不对的地方,欢迎指正。
今天就讲AOP,废话不多说,看干货。
AOP引入背景:
举个例字。我要写个管理系统,当然少不了用户验证这一阶段,但是,如果我用AOP思想,就可以不用先考虑登录验证问题,直接着手登录验证后的系统编写工作。把大部分工作处理完后,在反过来,在相应的位置处,添加验证功能。我做的系统添加验证功能的作用是,只要你登录系统,就要验证你的身份,当然,我们可以在登录的class中添加验证模块,但是耦合性就增加了,还有,如果 多个功能需要验证身份,那么也会增加代码的繁琐性和时候维护的工作量。面向切面的编程思想就很好的解决了这一问题,能随意地在想要的地方加入代码。这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。
这样看来,AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。有了AOP,OOP变得立体了。如果加上时间维度,AOP使OOP由原来的二维变为三维了,由平面变成立体了。从技术上来说,AOP基本上是通过代理机制实现的。
AOP,首先要知道几个概念。什么是切面?什么是切入点,这两个概念可以说最重要的。、
切面:我们管切入到指定类指定方法的代码片段称为切面;
切入点:切入到哪些类、哪些方法则叫切入点,就是切入的位置,即执行点;
然后,我用自己的小实例向大家展示:
方法一:注解版:
项目结构如下:
1.先写切入点所在的类service1 :
package service;
public class service1 {
public void name1() {
System.out.println("执行一;;;;;;;;;;;;;;;");
}
public void name2() {
System.out.println("执行二;;;;;;;;;;;;;;;");
}
public service1() {
}
public void name3() {
System.out.println("执行三;;;;;;;;;;;;;;;");
}
public void name4() {
System.out.println("执行四;;;;;;;;;;;;;;;");
}
public void name5() {
System.out.println("执行五;;;;;;;;;;;;;;;");
}public void name6() {
System.out.println("执行六;;;;;;;;;;;;;;;");
}
}
2.写待插入的切面类aspect :
package entity;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//设置切面,应用注解方式
@Aspect
public class aspect {
//执行点执行之前,执行切面方法
@Before("execution(* service.service1.name1(..))") //此注解直接将切面和执行点联系起来
public void before1(){
System.out.println("执行点执行之前执行,before1");
}
@Before("execution(* service.service1.name2(..))") //此注解直接将切面和执行点联系起来
public void before2(){
System.out.println("执行点执行之前执行,before2");
}
@Before("execution(* service.service1.name3(..))") //此注解直接将切面和执行点联系起来
public void before3(){
System.out.println("执行点执行之前执行,before3");
}
@Before("execution(* service.service1.name4(..))") //此注解直接将切面和执行点联系起来
public void before4(){
System.out.println("执行点执行之前执行,before4");
}
@Before("execution(* service.service1.name5(..))") //此注解直接将切面和执行点联系起来
public void before5(){
System.out.println("执行点执行之前执行,before5");
}
@Before("execution(* service.service1.name6(..))") //此注解直接将切面和执行点联系起来
public void before6(){
System.out.println("执行点执行之前执行,before6");
}
//执行点执行之后,执行切面方法
@After("execution(* service.service1.name1(..))")
public void after1(){
System.out.println("执行点执行之后执行,after1");
}
@After("execution(* service.service1.name2(..))")
public void after2(){
System.out.println("执行点执行之后执行,after2");
}
@After("execution(* service.service1.name3(..))")
public void after3(){
System.out.println("执行点执行之后执行,after3");
}
@After("execution(* service.service1.name4(..))")
public void after4(){
System.out.println("执行点执行之后执行,after4");
}
@After("execution(* service.service1.name5(..))")
public void after5(){
System.out.println("执行点执行之后执行,after5");
}
@After("execution(* service.service1.name6(..))")
public void after6(){
System.out.println("执行点执行之后执行,after6");
}
}
3.测试类:
package text;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.service1;
public class test {
@Test
public void test1() {
//通过容器,将两者的关系注入到各自的javabean中
ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");
service1 s = ac.getBean("s1",service1.class);//
s.name1();//执行此方法时,会自动寻找以此方法为执行点的的切面方法(注解已经标识),并根据相关的顺序执行相关的切面方法。
System.out.println();
s.name2();
System.out.println();
s.name3();
System.out.println();
s.name4();
System.out.println();
s.name5();
System.out.println();
s.name6();
}
}
4.配置文件如下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:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<bean id="s1" class="service.service1"></bean>
<bean id="as" class="entity.aspect"></bean>
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
5.运行结果:
注,需要加入相关的jar包,需要的联系我。