Spring——XML方式实现AOP编程

一.简介

  • 通过xml配置,配置目标类和切面类,<aop:config>标签将目标类和切面类融合
  • 可以将控制层,业务层和数据库访问层都看成一个切面,做统一的异常处理
    在这里插入图片描述

二.配置文件的各种通知

  • pointcut-ref是切入点指向,用来指明切面类各种通知配置到目标类的哪个目标方法中
  • 前置通知(aop:before):在目标方法执行前执行
    配置文件:<aop:before method="begin" pointcut-ref="point"/>
    应用:可以对方法的参数来做校验
  • 后置通知(aop:after-returning):目标方法执行后执行
    配置文件:<aop:after-returning method="commit" pointcut-ref="point"/>
    应用:可以修改方法的返回值
    目标方法有返回值可以通过配置后置通知的retuerning属性拿到返回值
    returning属性,将目标类返回值存在ret,切面类中可以通过给后置通知传Object ret获得返回的值
    如果目标方法有异常,后置通知不会执行
  • 异常通知(aop:after-throwing):目标方法出错时执行
    配置文件:<aop:after-throwing method="ex" pointcut-ref="point" thorwing="xx"/>
    应用:包装异常的信息
    异常内容会保存到xx里面
    配置异常通知的thorwing="xx"是切面类异常方法ex里面的参数Throwable xx
  • 最终通知(aop:after):不管什么时候都会执行
    配置文件:<aop:after method="finall" pointcut-ref="point"/>
    应用:释放资源
    如果目标方法有异常,最终通知也会执行
  • 环绕通知(aop:around):目标方法执行前后执行的方法,和前置后置通知重复,选择一个写即可
    配置文件:<aop:around method="around" pointcut-ref="point"/>
    环绕通知需要对目标方法进行放行

三.代码

1.目标类接口

package com.jp.aop;

import com.jp.domain.Person;

public interface PersonDao {
	void save(Person person);
	//int save(Person person);
}

2.目标类

package com.jp.aop;
import com.jp.domain.Person;

public class PersonDaoImpl implements PersonDao{
	@Override
	public void save(Person person) {
		//int i=1/0;//异常,会被捕捉报错
		System.out.println("保存Person成功...");
	}
	/*@Override
	public int save(Person person) {
		System.out.println("保存Person成功...");
		return 1;
	}*/
}

3.切面类

package com.jp.transcation;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyTranscation {
	public void begin(){
		System.out.println("开启事务");
	}
	public void commit(){
		System.out.println("提交事务");
	}
	/*public void commit(Object ret){
		System.out.println(ret);
		System.out.println("提交事务");
	}*/
	public void ex(Throwable xx){
		System.out.println(xx.getMessage());
		System.out.println("有异常了");
	}
	public void finall(){
		System.out.println("最终通知");
	}
	public void around(ProceedingJoinPoint p) throws Throwable{
		System.out.println("环绕通知前");
		//放行,执行目标方法
		p.proceed();
		System.out.println("环绕通知后");
	}
}
package com.jp.transcation;

public class Logger {
	public void log(){
		System.out.println("日志记录。。。");
	}
}
package com.jp.transcation;

public class Security {
	public void safe(){
		System.out.println("安全校验。。。");
	}
}

4.配置文件

applicationContext.xml要放在src下
execution切入点表达式

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.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.xsd">
	
	<!-- 目标类 -->
	<bean id="personDao" class="com.jp.aop.PersonDaoImpl"></bean>
	<!-- MyTranscation切面 -->
	<bean id="m" class="com.jp.transcation.MyTranscation"></bean>
	<!-- Logger切面 -->
	<bean id="log" class="com.jp.transcation.Logger"></bean>
	<!-- Security切面 -->
	<bean id="security" class="com.jp.transcation.Security"></bean>
	
	<!-- aop配置 -->
	<!-- pointcut-ref是切入点指向,用来指明切面类各种通知配置到目标类的哪个目标方法中 -->
	<aop:config>
		<!-- 切入点表达式配置,可以配置多个切面 -->
		<!-- expression="execution (com.jp.aop.PersonDaoImpl.*(..))"代表找到PersonDaoImpl类下任意方法 -->
		<aop:pointcut expression="execution (* com.jp.aop.PersonDaoImpl.*(..))" id="point"/>
		<!-- 切面配置,指配置切面类m的各种通知到目标类的目标方法中 -->
		<aop:aspect ref="m">
			<!-- 前置通知 -->
			<!-- <aop:before method="begin" pointcut-ref="point"/> -->
			<!-- 后置通知 -->
			<!-- <aop:after-returning method="commit" pointcut-ref="point"/> -->
			<!-- 异常通知 -->
			<!-- <aop:after-throwing method="ex" pointcut-ref="point" thorwing="xx"/> -->
			<!-- 最终通知 -->
			<!-- <aop:after method="finall" pointcut-ref="point"/> -->
			<!-- 环绕通知 -->
			<aop:around method="around" pointcut-ref="point"/>
		</aop:aspect>
		<!-- Logger切面配置 -->
		<aop:aspect ref="log">
			<aop:pointcut expression="execution (* com.jp.aop..*.*(..))" id="point2"/>
			<aop:before method="log" pointcut-ref="point2"/>
		</aop:aspect>
		<!-- Security切面配置 -->
		<aop:aspect ref="security">
			<!-- 代表PersonDaoImpl类下以s开头的方法 -->
			<aop:pointcut expression="execution (* com.jp.aop.PersonDaoImpl.s*(..))" id="point3"/>
			<aop:after method="safe" pointcut-ref="point3"/>
		</aop:aspect>
	</aop:config>
</beans>

5.测试类

package com.jp.aop;

import java.lang.reflect.Method;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jp.domain.Person;

public class SpringXmlTest {
	@Test
	public void test1(){
		ApplicationContext  ac=new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonDao personDao = (PersonDao)ac.getBean("personDao");
		Person person=new Person();
		personDao.save(person);
	}
	@Test
	public void test2(){
		Object o=new Object();
		Class class1=o.getClass();
		Method[] methods = class1.getMethods();
		for(Method m:methods){
			System.out.println(m);
		}
	}
}

四.Spring帮助文档下载

Spring帮助文档下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOPSpring框架中的一个重要模块,它提供了面向切面编程AOP)的支持。AOP是一种编程思想,它可以在不改变原有代码的情况下,通过在程序运行时动态地将代码“织入”到现有代码中,从而实现对原有代码的增强。 Spring AOP提供了基于注解的AOP实现,使得开发者可以通过注解的方式来定义切面、切点和通知等相关内容,从而简化了AOP的使用。 下面是一个基于注解的AOP实现的例子: 1. 定义切面类 ```java @Aspect @Component public class LogAspect { @Pointcut("@annotation(Log)") public void logPointcut() {} @Before("logPointcut()") public void beforeLog(JoinPoint joinPoint) { // 前置通知 System.out.println("执行方法:" + joinPoint.getSignature().getName()); } @AfterReturning("logPointcut()") public void afterLog(JoinPoint joinPoint) { // 后置通知 System.out.println("方法执行完成:" + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "logPointcut()", throwing = "ex") public void afterThrowingLog(JoinPoint joinPoint, Exception ex) { // 异常通知 System.out.println("方法执行异常:" + joinPoint.getSignature().getName() + ",异常信息:" + ex.getMessage()); } } ``` 2. 定义业务逻辑类 ```java @Service public class UserService { @Log public void addUser(User user) { // 添加用户 System.out.println("添加用户:" + user.getName()); } @Log public void deleteUser(String userId) { // 删除用户 System.out.println("删除用户:" + userId); throw new RuntimeException("删除用户异常"); } } ``` 3. 在配置文件中开启AOP ```xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.example"/> ``` 在这个例子中,我们定义了一个切面类LogAspect,其中通过@Aspect注解定义了一个切面,通过@Pointcut注解定义了一个切点,通过@Before、@AfterReturning和@AfterThrowing注解分别定义了前置通知、后置通知和异常通知。 在业务逻辑类中,我们通过@Log注解标注了需要增强的方法。 最后,在配置文件中,我们通过<aop:aspectj-autoproxy/>开启了AOP功能,并通过<context:component-scan>扫描了指定包下的所有组件。 这样,当我们调用UserService中的方法时,就会触发LogAspect中定义的通知,从而实现对原有代码的增强。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值