1、什么是AOP
AOP是Aspect Oriented Programing的简称,面向切面编程(面向方面编程),通过方式(静态代理)和运行期(动态代理)实现程序功能的统一维护的一种技术,AOP是的延续,是框架中的一个重要内容,利用AOP可以对业务逻辑的各个部分进行隔离(Struts2的拦截器设计就是基于AOP的思想)
2、Spring AOP 主要是利用代理模式的技术来实现的
Spring默认使用JDK动态代理,在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理,不过现在的项目都是面向接口编程,所以JDK动态代理相对来说用的还是多一些
►1、Spring AOP-Annotation方式
第一步:增加aop依赖、sping xml文件增加aop命名空间
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
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 ">
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
第二步:增加代理类
//增加代理类及切面注解
@Aspect
public class MyProxy2 {
@Before("execution(public void com.service.StuServiceImp.show())")
public void printbefore() {
System.out.println("方法之前执行了");
}
@After("execution(public void com.service.StuServiceImp.show())")
public void printafter() {
System.out.println("方法之后执行了");
}
}
第三步:增加被代理人接口及实现类
public interface StuServiceI{
void show();
void show(int a);
String show(String s);
}
public class StuServiceImp {
public void show() {
System.out.println("StuServiceImp show 方法");
}
public void show(int a) {
System.out.println("StuServiceImp show 方法" + a);
}
public String show(String s) {
System.out.println("StuServiceImp show 方法" + s);
return null;
}
}
第四步:spring xml文件增加aop:aspectj-autoproxy切面
<!--启用@Aspect切面支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 代理人方面类 -->
<bean id="myproxy2" class="com.test.MyProxy2"></bean>
<!-- 被代理类 -->
<bean id="stuserviceimp" class="com.service.StuServiceImp"></bean>
第五步:测试
public static void main(String[] args) throws InterruptedException {
ApplicationContext acx = new ClassPathXmlApplicationContext("applicationContext.xml");
StuServiceImp a = (StuServiceImp) acx.getBean("stuserviceimp");
a.show();//会执行代理类的方法
a.show(2);//不会执行代理类的方法
►2、Spring AOP-xml方式
第一步:spring xml开始aop配置
<!-- aop配置 -->
<aop:config>
<aop:pointcut
expression="execution(public void com.service.StuServiceImp.show(..))"
id="ex" /><!-- 对应切入点 -->
<aop:aspect id="asp" ref="myproxy2"><!-- 通知者 -->
<aop:before method="printbefore" pointcut-ref="ex" /><!-- method="printbefore"是通知者的一个方法 -->
</aop:aspect>
</aop:config>
<!-- 代理人方面类 -->
<bean id="myproxy2" class="com.test.MyProxy2"></bean>
<!-- 被代理类 -->
<bean id="stuserviceimp" class="com.service.StuServiceImp"></bean>
第二步:测试
ApplicationContext acx = new ClassPathXmlApplicationContext("applicationContext.xml");
StuServiceImp a = (StuServiceImp) acx.getBean("stuserviceimp");
a.show();//会执行代理类的方法
a.show(2);//不会执行代理类的方法
4、Spring Annotation(注解)配置bean对象注入
第1步:在配置文件中引入context命名空间,使用context:component-scan标签指明扫描包(@component 标记)
<!-- 到哪些包中扫描bean(@component 标记好的) -->
<context:component-scan base-package="com.bean,com.test"></context:component-scan>
第2步:在扫描包下面的类前面加上@component 注解,依赖属性前面加上@Resource(name="b")
相当于在配置文件中配置一个单例模式的bean,这个bean的id默认类名,但首字母变成小写形式。可以通过如下注解语法更改bean的id
@Component(value="a")
public class A {
@Resource(name="b")
B b;
public void a(){
b.b();
System.out.println("aa");
}
}
@Component
public class B {
public void b() {
System.out.println("bb");
}
}
第3步:测试
public static void main(String[] args) {
ApplicationContext acx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
A a = (A) acx.getBean("a");
a.a();
}
5、拆分配置文件
►拆分原因
项目规模变大,配制文件可读性、可维护性差
团队开发时,多人修改同一配置文件,易发生冲突
►拆分策略
1、公用配置+每个软件模块一个单独配置文件(包含dao、service、action)
2、公用配置+DAO Bean配置+业务逻辑Bean配置+Action Bean配置
►拆分语法有两种:
1、使用<import resource="x.xml"/>方式 <import resource="applicationContext2.xml" />
2、配制Spring集成时:配制ContextLoadListener的contextConfigLocation属性,配置多个配置文件用,逗号隔开;或者使用通配符