定义切面通知

@Aspect

Spring使用AspectJ来申明通知方法。

注解通知
@After通知方法会在目标返回或抛出异常时调用
@AfterReturning通知方法会在目标返回后调用
@AfterThrowing通知方法在目标抛出异常时调用
@Around通知方法将目标方法封装起来
@Before通知方法在目标方调用前执行

@Pointcut

可以通过@Pointcut注解申明频繁使用的切点表达式

@EnableAspectJAutoProxy

启动AspectJ自动代理
如果使用xml,需要使用Spring命名空间中国的<aop: aspectj-autoproxy>。

示例

Performance 接口

public interface Performance {
	void perform(String performContent);
}

表演实现类

@Component
public class Concert implements Performance {

	@Override
	public void perform(String performContent) {
		System.out.println(performContent + "表演中。。。");
	}

}

定义切面(@Pointcut + @Before + @Around + args)
args:处理通知中的参数。

@Aspect
public class Audience {
	@Pointcut("execution(* com.zachary.aop.Performance.perform(String)) && args(performContent)")
	public void performance(String performContent) {};
	
	@Before("performance(performContent)")
	public void silenceCellPhones(String performContent) {
		System.out.println(performContent + "Sliencing cell phones");
	}
		
	@Around("performance(performContent)")
	public void watchPerformance(ProceedingJoinPoint jp, String performContent) {
		try {
			System.out.println(performContent);
			System.out.println("Taking seats");
			jp.proceed();
			System.out.println("CLAP CLAP CLAP!!!");
		} catch (Throwable e) {
			System.out.println("Demand a refund");
			e.printStackTrace();
		}
	}
}

JavaConfig配置

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
	@Bean
	public Audience audience() {
		return new Audience();
	}
}

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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
		https://www.springframework.org/schema/context/spring-context.xsd">
	
	<context:component-scan base-package="com.zachary.aop"/>
	
	<aop:aspectj-autoproxy />
</beans>

注意:xml中不需要,如果添加了会生成两个切面。执行时会执行两遍。
测试

@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = ConcertConfig.class)
@ContextConfiguration(locations = "classpath:aop-config.xml")
public class ConcertConfigTest {
	@Autowired
	private Performance concert;
	
	@Test
	public void test() {
		concert.perform();
	}
}

执行调用方法初始化Spring上下文:
通过JavaConfig配置初始化

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConcertConfig .class);
Person person = (Person) ctx.getBean("concert");

通过xml配置初始化

AbstractApplicationContext context = new FileSystemXmlApplicationContext("classpath:aop-config.xml");
Performance concert = (Performance) context.getBean("concert");
要使用自定义注解定义切面,你可以结合使用AspectJ和自定义注解。以下是一个示例代码: 1. 首先,定义一个自定义注解,用于标记需要应用切面的方法: ```java import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface LogExecutionTime { } ``` 2. 创建一个切面类,使用AspectJ注解来定义切面逻辑: ```java import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Around("@annotation(LogExecutionTime)") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); long endTime = System.currentTimeMillis(); long executionTime = endTime - startTime; System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms"); return result; } } ``` 在上面的示例中,我们使用`@Around`注解来定义一个环绕通知,它会在带有`@LogExecutionTime`注解的方法执行前后进行处理。在环绕通知中,我们记录了方法的执行时间,并打印出来。 3. 在需要应用切面的方法上添加`@LogExecutionTime`注解: ```java @Service public class MyService { @LogExecutionTime public void myMethod() { // 方法实现 } } ``` 在上面的示例中,我们在`myMethod`方法上添加了`@LogExecutionTime`注解。 4. 配置AspectJ和扫描切面: 如果使用Spring框架,你需要在配置文件中启用AspectJ自动代理,并扫描切面类。 XML配置: ```xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.your.package"/> ``` Java配置: ```java @Configuration @EnableAspectJAutoProxy @ComponentScan(basePackages = "com.your.package") public class AppConfig { // 配置其他Bean } ``` 使用上述示例代码,你可以定义自己的切面,通过自定义注解来标记需要应用切面的方法,并在切面定义相应的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值