1.aop的作用
aop是面向切面编程的语言,它可以让你的业务代码和非业务代码进行隔离。在不改变业务代码的前提下,可以增加新的非业务代码。
2.Aspect(切面)
Aspect(切面)由Pointchu(切点)和Advice(处理)组成
这里需要引入相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
</dependencies>
以及配置spring.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.zjh.aop"/>
<aop:aspectj-autoproxy/>
</beans>
Pointcut可以通过两种方式创建:
1.通过路径表达式创建
@Service
public class UserServiceImpl implements UserService {
@Override
public Integer selectByid() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
@Override
public Integer deleteById() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
}
@Aspect
@Component
public class MyAspect {
@Pointcut(value = "execution(* com.zjh.service.impl.*.*())")//括号内是(public Intiger com.zjh.service.impl.UserServiceImpl.selectByid())的缩写
public void myaspect1(){};
}
2.通过注解创建
@Service
public class UserServiceImpl implements UserService {
@MyAnnotation
@Override
public Integer selectByid() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
@MyAnnotation
@Override
public Integer deleteById() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
}
@Aspect
@Component
public class MyAspect {
@Pointcut(value = "@annotation(com.zjh.annotation.MyAnnotation)")//括号内为自定义注解的路径
public void myaspect(){};
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
Advice的处理时机有:Before(前置处理)、After(后置处理)、Around(环境处理)、AfterReturning(后置返回通知)、AfterThrowing(异常处理)几种类别。其中Around(环境处理)用的最为广泛。
@Service
public class UserServiceImpl implements UserService {
@MyAnnotation
@Override
public Integer selectByid() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
@MyAnnotation
@Override
public Integer deleteById() {
System.out.println("执行了该方法");
int i=10/0;
return null;
}
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
@Aspect
@Component
public class MyAspect {
@Pointcut(value = "execution(* com.zjh.service.impl.*.*())")//括号内是(public Intiger com.zjh.service.impl.UserServiceImpl.selectByid())的缩写
public void myaspect1(){};
@Pointcut(value = "@annotation(com.zjh.annotation.MyAnnotation)")
public void myaspect(){
};
@Around(value = "myaspect()")//填写切点方法名
public Object ar(ProceedingJoinPoint joinPoint){
System.out.println("相当于前置处理");
try {
joinPoint.proceed();//执行方法
System.out.println("相当于后置返回通知");//执行方法发生异常则不会有此通知
return 666;//代理返回值
} catch (Throwable e) {
System.out.println("相当于异常处理");
} finally {
System.out.println("相当于后置处理");//该处理必定会执行
}
return null;
}
}
public class work01 {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("classpath:spring.xml");
UserService userServiceImpl = (UserService) app.getBean("userServiceImpl");//强转为实现类的接口类型
System.out.println(userServiceImpl.selectByid());//执行结果打印顺序为:相当于前置处理 执行了该方法 相当于异常处理 相当于后置处理 null
}
}
3.spring的事务处理
将事务交给spring需要在spring.xml里加入事务管理
<!--事务切面管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务管理注解的驱动-->
<tx:annotation-driven/>
然后在需要事务管理的方法上加上@Transactional注解即可把事务交给spring管理
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountDao accountDao;
@Transactional
@Override
public Integer zhuanzhang(int id,int uid,double money) {
accountDao.updateMoney(-money,id);
int i=10/0;
Integer integer = accountDao.updateMoney(money, uid);
return integer;
}
}