一般切面的 AOP 开发
当我们在使用 Spring AOP 开发时,若没有对切面进行具体定义,Spring AOP 会通过 Advisor 为我们定义一个一般切面(不带切点的切面),然后对目标对象(Target)中的所有方法连接点进行拦截,并织入增强代码。
工程依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ssw</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.6</version>
</dependency>
</dependencies>
</project>
userdao接口:
package org.example.dao;
public interface UserDao
{
public void add();
public void delete();
public void modify();
public void get();
}
实现userdao接口:
package org.example.dao.impl;
import org.example.dao.UserDao;
public class UserDaoImpl implements UserDao
{
@Override
public void add() {
System.out.println("正在执行 UserDao 的 add() 方法……");
}
@Override
public void delete() {
System.out.println("正在执行 UserDao 的 delete() 方法……");
}
@Override
public void modify() {
System.out.println("正在执行 UserDao 的 modify() 方法……");
}
@Override
public void get() {
System.out.println("正在执行 UserDao 的 get() 方法……");
}
}
设置前置正确方法UserDaoBeforeAdvice:
package org.example.advice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* 增强代码
* MethodBeforeAdvice 前置增强
*
* @author c语言中文网 c.biancheng.net
*/
public class UserDaoBeforeAdvice implements MethodBeforeAdvice
{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable
{
System.out.println("正在执行前置增强操作…………");
}
}
设置bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--******Advisor : 代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)*******-->
<!-- 定义目标(target)对象 -->
<bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="org.example.advice.UserDaoBeforeAdvice"></bean>
<!--通过配置生成代理 UserDao 的代理对象 -->
<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="userDao"/>
<!-- 设置实现的接口 ,value 中写接口的全路径 -->
<property name="proxyInterfaces" value="org.example.dao.UserDao"/>
<!-- 需要使用value:增强 Bean 的名称 -->
<property name="interceptorNames" value="beforeAdvice"/>
</bean>
</beans>
执行方法:
package org.example;
import org.example.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main
{
public static void main(String[] args)
{
//获取 ApplicationContext 容器
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//获取代理对象
UserDao userDao = context.getBean("userDaoProxy", UserDao.class);
//调用 UserDao 中的各个方法
userDao.add();
userDao.delete();
userDao.get();
userDao.modify();
}
}
=======================================================================================
设置后置增强:
创建UserDaoAfterAdvice类:
package org.example.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class UserDaoAfterAdvice implements AfterReturningAdvice
{
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable
{
System.out.println("正在执行后置增强操作…………");
}
}
修改bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--******Advisor : 代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)*******-->
<!-- 定义目标(target)对象 -->
<bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="org.example.advice.UserDaoBeforeAdvice"></bean>
<!-- 定义增强 -->
<bean id="afterAdvice" class="org.example.advice.UserDaoAfterAdvice"></bean>
<!--通过配置生成代理 UserDao 的代理对象 -->
<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="userDao"/>
<!-- 设置实现的接口 ,value 中写接口的全路径 -->
<property name="proxyInterfaces" value="org.example.dao.UserDao"/>
<!-- <!– 需要使用value:增强 Bean 的名称 –>-->
<!-- <property name="interceptorNames" value="beforeAdvice"/>-->
<!-- 需要使用value:增强 Bean 的名称 -->
<property name="interceptorNames" value="afterAdvice"/>
</bean>
</beans>
执行代码:
package org.example;
import org.example.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main
{
public static void main(String[] args)
{
//获取 ApplicationContext 容器
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//获取代理对象
UserDao userDao = context.getBean("userDaoProxy", UserDao.class);
//调用 UserDao 中的各个方法
userDao.add();
userDao.delete();
userDao.get();
userDao.modify();
}
}
=======================================================================================
环绕增强:
创建UserDaoAroundAdvice类:
package org.example.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class UserDaoAroundAdvice implements MethodInterceptor
{
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable
{
System.out.println("基于Spring AOP的环绕增强前置处理.....");
Object res = null;
try
{
res=methodInvocation.proceed();//调用目标方法 返回目标方法的返回结果
}
catch (Throwable e)
{
e.printStackTrace();
}
System.out.println("基于Spring AOP的环绕增强后置处理.....");
return res;
}
}
修改bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--******Advisor : 代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)*******-->
<!-- 定义目标(target)对象 -->
<bean id="userDao" class="org.example.dao.impl.UserDaoImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="org.example.advice.UserDaoBeforeAdvice"></bean>
<!-- 定义增强 -->
<bean id="afterAdvice" class="org.example.advice.UserDaoAfterAdvice"></bean>
<!-- 定义增强 -->
<bean id="aroundAdvice" class="org.example.advice.UserDaoAroundAdvice"></bean>
<!--通过配置生成代理 UserDao 的代理对象 -->
<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="userDao"/>
<!-- 设置实现的接口 ,value 中写接口的全路径 -->
<property name="proxyInterfaces" value="org.example.dao.UserDao"/>
<!-- <!– 需要使用value:增强 Bean 的名称 –>-->
<!-- <property name="interceptorNames" value="beforeAdvice"/>-->
<!-- <!– 需要使用value:增强 Bean 的名称 –>-->
<!-- <property name="interceptorNames" value="afterAdvice"/>-->
<!-- 需要使用value:增强 Bean 的名称 -->
<property name="interceptorNames" value="aroundAdvice"/>
</bean>
</beans>
执行代码:
package org.example;
import org.example.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main
{
public static void main(String[] args)
{
//获取 ApplicationContext 容器
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//获取代理对象
UserDao userDao = context.getBean("userDaoProxy", UserDao.class);
//调用 UserDao 中的各个方法
userDao.add();
userDao.delete();
userDao.get();
userDao.modify();
}
}
=======================================================================================