您的当前位置:首页正文

Spring面向切面编程(AOP)

2024-11-29 来源:个人技术集锦

面向切面编程(AOP)

1、什么是AOP

AOP是Aspect Oriented Programing的简称,面向切面编程(面向方面编程),通过方式(静态代理)和运行期(动态代理)实现程序功能的统一维护的一种技术,AOP是的延续,是框架中的一个重要内容,利用AOP可以对业务逻辑的各个部分进行隔离(Struts2的拦截器设计就是基于AOP的思想)

2Spring 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);//不会执行代理类的方法

4Spring 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,这个beanid默认类名,但首字母变成小写形式。可以通过如下注解语法更改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属性,配置多个配置文件用,逗号隔开;或者使用通配符

显示全文