Spring之AOP切面编程

    xiaoxiao2022-07-12  160

    首先通过一张图(随便找的)来说明AOP原理:

    当执行一个程序时,需要执行一系列的方法,例如在数据库的增加数据(Service--dao--DB)这一过程中,我们可以在Service层中添加逻辑判断方法,AOP就是通过不改变Service中的代码,而加入了逻辑判断方法,通过切入点和切面的配置就可以达到这一效果。

     

    以模拟向数据库Student表中添加学生来实现AOP

    1.AOP的基本概念

    (1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

    (2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

    (3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around

    (4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

    (5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。

    2.Dao层

    创建接口 IStudentDao.java

    package com.zy.dao; public interface IStudentDao { void addStudent(String msg); }

    创建接口实现 StudentDaoImpl.java   这里知识模拟数据库操作,没有连接数据库了。

    package com.zy.dao.impl; import com.zy.dao.IStudentDao; public class StudentDaoImpl implements IStudentDao{ @Override public void addStudent(String msg) { System.out.println("添加学生:"+msg); } }

    3.Service层

    创建接口IStudentService.java

    package com.zy.service; public interface IStudentService { void addStudent(String msg); }

    接口实现StudentServiceImpl.java

    package com.zy.service.impl; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zy.dao.IStudentDao; import com.zy.service.IStudentService; public class StudentServiceImpl implements IStudentService{ IStudentDao studentDao; public void setStudentDao(IStudentDao studentDao) { this.studentDao = studentDao; } @Override public void addStudent(String msg) { studentDao.addStudent(msg); } }

    4.Advice(增强通知,接口实现方式)

    需要在执行Service层的addStudent()方法之前执行(这是前置增强,需要实现MethodBeforeAdvice接口)

    创建BeforeAop.java

    package com.zy.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class BeforeAop implements MethodBeforeAdvice{ // method : 切入的方法 <br> // args :切入方法的参数 <br> // target :目标对象 @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("-----接口前置增强5555-----"); System.out.println("method:"+method.getName()+"\nargs:"+args.length+"\ntarget:"+target.getClass()); } }

    5.配置applicationContext.xml

    Dao层注入(这里没有连接数据库,所以不用注入数据库信息,只需要配置bean即可)Service层注入配置切点(需要被增强的类)配置切面(需要插入增强类的方法)将切点和切面连接 <?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Dao层 --> <bean id="studentDao" class="com.zy.dao.impl.IStudentDaoImpl"></bean> <!-- Service层 --> <bean id="studentService" class="com.zy.service.impl.StudentServiceImpl"> <property name="studentDao" ref="studentDao"></property> </bean> <!-- 需要插入的方法 当作切点 --> <bean id="beforeAop" class="com.zy.aop.BeforeAop"></bean> <!-- 通过接口实现前置增强 --> <aop:config> <!-- 切面配置 所需要插入前置的方法 多个切面连接用or --> <aop:pointcut expression="execution(void com.zy.service.impl.StudentServiceImpl.addStudent(String))" id="pointCut"/> <!-- 切点配置 插入的方法--> <aop:advisor advice-ref="beforeAop" pointcut-ref="pointCut"/> </aop:config> </beans>

    6.测试类

    创建StudentTest.java

    package com.zy.test; import java.applet.AppletContext; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zy.service.IStudentService; public class StudentTest { public static void main(String[] args) { testAop(); // testDelStuAop() ; } // 增加学生的AOP测试 private static void testAop() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); IStudentService studentService = (IStudentService) ac.getBean("studentService"); studentService.addStudent("学生1"); } }

    7.运行结果

    通过接口实现前置可以拿到         method : 切入的方法         args :切入方法的参数         target :目标对象

     

    最新回复(0)