Spring基础(15)——AOP——BeforeAdvice

通知包含了切面的逻辑,所以当创建一个通知对象时,即编写实现交叉功能的代码,而且Spring连接点模型建立在方法拦截上。这标识编写的Spring通知会在方法调用周围各个地方织入系统中。因为Spring可以在方法执行的多个地方织入通知,所以有多种通知类型。

前置通知(Before Advice):在目标执行之前被调用。对应接口BeforeAdvice

后置通知(After Returning Advice):在目标方法执行之后调用。对应接口AfterReturnAdvice

异常通知(After Throwing Advice):在目标方法抛出异常后调用。对应接口ThrowAdvice

环绕通知(Around Advice):在目标方法执行前后被调用。对应接口MethodInterceptor

引入通知(Introduction Advice):在目标类中添加一些新的方法和属性

前置通知(Before Advice)

java用法:

package test.advice;

public interface Reception {
	public void serveCustomer(String customName);
}
package test.advice;

public class ConcreteReception implements Reception {

	@Override
	public void serveCustomer(String customName) {
		// TODO Auto-generated method stub
		System.out.println("我正在服务客户:" + customName);
	}

}
package test.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class GreetingBeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		String customerName = (String) args[0];
		System.out.println("欢迎:" + customerName + " ,很高兴为您服务");
	}

}
package test.advice;

import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;

public class Test {

	public static void main(String[] args) {
		Reception target = new ConcreteReception();
		BeforeAdvice advice = new GreetingBeforeAdvice();
		ProxyFactory pf = new ProxyFactory();
		pf.setTarget(target);
		pf.addAdvice(advice);
		Reception proxy = (Reception) pf.getProxy();
		proxy.serveCustomer("HeMaSoft.com");
	}

}
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"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	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/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">


	<bean id="greetingBeforeAdvice"
		class="test.advice.GreetingBeforeAdvice">
	</bean>
	<bean id="reception"
		class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces"
			value="test.advice.Reception"></property>

		<property name="interceptorNames"
			value="greetingBeforeAdvice">
		</property>
		<property name="target" ref="target"></property>
	</bean>
	<bean id="target" class="test.advice.ConcreteReception"></bean>
</beans>
package test.advice;

import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

	public static void main(String[] args) {
//		Reception target = new ConcreteReception();
//		BeforeAdvice advice = new GreetingBeforeAdvice();
//		ProxyFactory pf = new ProxyFactory();
//		pf.setTarget(target);
//		pf.addAdvice(advice);
//		Reception proxy = (Reception) pf.getProxy();
//		proxy.serveCustomer("HeMaSoft.com");
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-servlet.xml");
		Reception reception = (Reception) context.getBean("reception");
		reception.serveCustomer("Test");
	}

}

ProxyFactoryBean是FactoryBean接口的实现类,负责为其他Bean创建代理实例,在内部使用ProxyFactory来完成这一工作。

target 代理目标的对象

proxyInterfaces 代理所有实现的接口,可以是多个接口。该属性还有一个别名属性interfaces

interceptorNames 需要织入目标对象的前置通知类数组(必须采用全限定类名),在内部interceptorNames是一个字符串数组,ProxyFactoryBean通过反射机制获取对应的类,他们可以是拦截器、通知或者包含通知的切入的advisor,配置中的顺序对应调用的顺序

singleton 返回的代理是否是单例,默认为单例

optimize 当设置为true时,强制使用CGLIB代理。对于其他作用域类型的代理,最好使用JDK代理。CGLIB创建代理的速度慢,而产生出的代理对象运行效率高,jdk代理相反

proxyTargetClass 是否对类惊醒代理,而不是对接口进行代理,设置为true时,使用CGLib代理。






  • 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、付费专栏及课程。

余额充值