当前位置: 首页 > 工具软件 > Spring-Monkey > 使用案例 >

Spring框架---day08

盖马鲁
2023-12-01

Spring框架—day08

注解方式实现aop的操作

Aspectj进行切面实现aop—他是一个专门做出来进行注解方式开发的。

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

通过aspectj来进行注解式的开发。

例子—有一个猴子, 还有一个果园,在这个果园中有一个管理员; 当猴子不来偷东西的时候,就不会抓他,当猴子走到果园偷桃子时就会触发通知,管理员知道有猴子偷东西。

1.在pom文件中加入aspectj的注解

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.9.1</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.1</version>
            </dependency>

2.写主要的类

//主流业务类
public class Monkey {
	public void stealPeaches(String name) {
		System.out.println("我是猴子,我要去偷桃子,我叫"+name);
	}
}

3.写切面

//切面  猴子跑过来偷桃就会触发事件
//加入aspect这个注解就是一个切面
@Aspect
public class Guardian {
	//切入点    当猴子不偷桃时就不会切入进去,一偷桃就切入
	@Pointcut("execution(* com.zll.aop.Monkey.stealPeaches(..))")
	public void foundMonkey() {
		
	}
	//前置通知
	@Before(value = "foundMonkey()")
	public void foundBefore() {
		System.out.println("等猴子偷桃时就抓住它");
	}
	@AfterReturning(value = "foundMonkey() && args(name,..)")
	public void foundAfter(String name) {
		System.out.println("猴子偷桃被抓住了,他叫"+name);
	}
}

4.在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 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-2.0.xsd">
		<bean id="monkey" class="com.zll.aop.Monkey"></bean>
		<bean id="guardian" class="com.zll.aop.Guardian"></bean>
		 <!-- 支持aspectj -->
       	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

这个地方可以通过xml文件注入,也可以通过注解注入

5.测试

public class Test {
	public static void main(String[] args) {
		ApplicationContext app=new ClassPathXmlApplicationContext("bean.xml");
		Monkey monkey=app.getBean("monkey", Monkey.class);
		monkey.stealPeaches("孙悟空");
		
	}
}

spring aop的例子 日志

注解方式写日志

接口

public interface UserService {
	void addUser();
	void delUser();
	void updateUser();
	void find();
}

业务

@Component
public class UserServiceImpl implements UserService{

	public void addUser() {
		System.out.println("-----用户被添加-----");
		
	}

	public void delUser() {
		System.out.println("-----用户被删除-----");
		
	}

	public void updateUser() {
		//int a=10/0;
		System.out.println("-----用户被更新-----");
		
	}

	public void find() {
		System.out.println("-----用户被查找-----");
		
	}

}

切面

@Component
@Aspect
public class LogAdvice {
	//前置通知  括号内是约束条件 对方法名字内带 User起作用
	@Before("execution(void *User(..))")
	public void before(JoinPoint jp) {
		//切入点,获取目标对象名称
		String name=jp.getSignature().getName();
		System.out.println("-----前置通知启动------目标对象业务名称:"+name);
	}
	
	//后置通知
	@After("execution(void *User(..))")
	public void After(JoinPoint jp) {
		String name=jp.getSignature().getName();
		System.out.println("-----后置通知启动------目标对象业务名称:"+name);
	}
	//环绕通知
	@Around("execution(void *find(..))")
	public void Around(ProceedingJoinPoint pj) throws Throwable {
		String name=pj.getSignature().getName();
		System.out.println("-----环绕通知启动------目标对象业务名称:"+name);
		pj.proceed();
		System.out.println("-----环绕通知结束------目标对象业务名称:"+name);
	}


	
	@AfterReturning("execution(void *User(..))")
	public void final01(JoinPoint jp) {
		String name=jp.getSignature().getName();
		System.out.println("-----最终通知执行------目标对象业务名称:"+name);
	}
	
	//异常通知
	@AfterThrowing("execution(void *User(..))")
	public void execption(JoinPoint jp) {
		String name=jp.getSignature().getName();
		System.out.println("-----执行出现异常-----"+name+"里面存在异常");
	}
}

测试

public class Test {
	public static void main(String[] args) {
		ApplicationContext app=new ClassPathXmlApplicationContext("bean.xml");
		UserService userService=app.getBean("userServiceImpl",UserService.class);
		userService.addUser();
		userService.delUser();
		userService.updateUser();
		userService.find();
	}
}

xml文件

<!--自动扫描我们的包 -->
        <context:component-scan base-package="com.zll.aop"></context:component-scan>
       
        <!--开启注解方式来实现aop 自动代理-->
       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

aop 事务

Spring常用的一个aop的例子就是事务管理, 增删改操作,都会需要事务管理, 就需要我们配置一个切面, 当你的这三个方法走到切面的时候, 进行事务操作。

Spring中七种Propagation类的事务属性详解:

REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。

MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。

REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

使用xml文件进行事务的操作很麻烦。

 类似资料: