SpringAop入门学习(注解与配置文件版)
一、使用注解形式来完成Aop学习
步骤一:
创建maven项目,在pom.xml文件中输入以下两个坐标:
<dependencies>
<!-- spring坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!-- spring-aop坐标-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
步骤二:
创建UserDao接口类
package com.zhicheng.lq.dao;
public interface UserDao {
void save();
}
创建UserDaoImp实现类,并且添加@Repository注解
package com.zhicheng.lq.dao.Imp;
import com.zhicheng.lq.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImp implements UserDao {
public void save() {
System.out.println("我是实现类中的save方法!");
}
}
步骤三:
创建SpringConfig配置类
@EnableAspectJAutoProxy:启动了Aop类中的@Aspect注解 的功能
package com.zhicheng.lq.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(value = "com.zhicheng.lq")
@EnableAspectJAutoProxy
public class SpringConfig {
}
步骤四:
创建SpringAopTest类为Aop类
@Aspect:把当前类标识为一个切面供容器读取(定义切面Aop类)
@Pointcut:表示需要注入aop功能的方法范围
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行
package com.zhicheng.lq.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class SpringAopTest {
/**
* 定义切入点
* 在通知类中,定义一个空的private方法,在其上添加注解@Pointcut("execution(返回值类型 包名.类.方法)")
* @Pointcut注解表示需要注入aop功能的方法范围
*/
@Pointcut("execution(void com.zhicheng.lq.dao.UserDao.save())")
private void test(){}
@Before("test()")
public void methodTest(){
System.out.println("我是测试方法!");
}
}
步骤五:
编写Test测试类
package com.zhicheng.lq;
import com.zhicheng.lq.config.SpringConfig;
import com.zhicheng.lq.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
UserDao userDao=ac.getBean(UserDao.class);
userDao.save();
}
}
结果展示:
二、使用配置形式来完成
步骤一:
与上方步骤一相同。
步骤二:
编写UserService接口类
package com.zhicheng.lq.service;
public interface UserService {
public void doSomething();
public void doSecondthing();
public void doThirdthing();
public void doFourThing();
public void saveFiveThing();
//业务方法带有返回值
public String querySixthThing();
public void getSeventhThing() throws ArrayIndexOutOfBoundsException;
public void seckill();
}
编写UserServiceImp实现类
package com.zhicheng.lq.service.imp;
import com.zhicheng.lq.service.UserService;
public class UserServiceImp implements UserService {
@Override
public void doSomething() {
System.out.println("call doSomething method");
//LogUtils.doLog();
}
@Override
public void doSecondthing() {
// ValidateUtils.doValidate();
System.out.println("call doSecondthing method");
//LogUtils.doLog();
}
@Override
public void doThirdthing() {
//ValidateUtils.doValidate();
System.out.println("call doThirdthing method");
//LogUtils.doLog();
}
public void doFourThing() {
System.out.println("call doFourThing method");
}
@Override
public void saveFiveThing() {
System.out.println("call saveFiveThing method");
}
@Override
public String querySixthThing() {
System.out.println("call doSixthThing method");
return "It is hot today";
}
@Override
public void getSeventhThing() throws ArrayIndexOutOfBoundsException {
System.out.println("call getSeventhThing method");
int[] arr = {1, 33, 56, 77};
try {
System.out.println(arr[10]);
} catch (Exception e) {
throw new ArrayIndexOutOfBoundsException("数组越界啦:(");
}
}
@Override
public void seckill() {
System.out.println("call seckill method begin.....");
//模拟执行3s钟
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("call seckill method end.....");
}
}
步骤三:
编写MyAspect切面类代码:
package com.zhicheng.lq.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
public void before333(){
System.out.println("----前置通知-----");
// ValidateUtils.doValidate(); //身份验证
}
public void after(){
System.out.println("----后置通知-----");
// LogUtils.doLog(); //日志记录
}
public void afterReturning(Object obj){
System.out.println("----后置返回通知-----");
System.out.println("MyAspect message:"+obj);
}
public void afterThrowing(Throwable t){
System.out.println("----后置异常通知-----");
//AOP获取业务代码的异常信息
System.out.println("MyAspect Handle Exception:"+t.getMessage());
}
//ProceedingJoinPoint 连接点
public void aroundPerformence(ProceedingJoinPoint pjp){
System.out.println("----AOP aroundPerformence begin----");
//记录开始时间
long beginTime=System.currentTimeMillis();
try {
//AOP中通知 执行业务代码
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
//记录结束时间
long endTime=System.currentTimeMillis();
System.out.println("AOP take times:"+(endTime-beginTime)+"ms");
System.out.println("----AOP aroundPerformence end----");
}
}
步骤四:
编写spring_aop.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--定义核心业务类-->
<bean id="userService" class="com.zhicheng.lq.service.imp.UserServiceImp"></bean>
<!--定义切面类-->
<bean id="myAspect" class="com.zhicheng.lq.aop.MyAspect"></bean>
<!--定义AOP-->
<aop:config>
<!--定义切点-->
<aop:pointcut id="myPointcut1" expression="execution(* com.zhicheng.lq.service.UserService.do*(..))"/>
<aop:pointcut id="myPointcut2" expression="execution(* com.zhicheng.lq.service.UserService.query*(..))"/>
<aop:pointcut id="myPointcut3" expression="execution(* com.zhicheng.lq.service.UserService.get*(..))"/>
<aop:pointcut id="myPointcut4" expression="execution(* com.zhicheng.lq.service.UserService.sec*(..))"/>
<!--定义切面-->
<aop:aspect ref="myAspect">
<!--定义通知-->
<aop:before method="before333" pointcut-ref="myPointcut1"></aop:before>
<aop:after method="after" pointcut-ref="myPointcut1"></aop:after>
<aop:after-returning method="afterReturning" pointcut-ref="myPointcut2" returning="obj"></aop:after-returning>
<aop:after-throwing method="afterThrowing" pointcut-ref="myPointcut3" throwing="t"></aop:after-throwing>
<aop:around method="aroundPerformence" pointcut-ref="myPointcut4"></aop:around>
</aop:aspect>
</aop:config>
</beans>
步骤五:
编写Tset测试类代码:
package com.zhicheng.lq.test;
import com.zhicheng.lq.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// IUserService userService=new UserServiceImpl();
ApplicationContext ac=new ClassPathXmlApplicationContext("spring_aop.xml");
UserService userService=(UserService) ac.getBean("userService");
userService.doSomething();
userService.doSecondthing();
userService.doThirdthing();
userService.doFourThing();
userService.saveFiveThing();
userService.querySixthThing();
//userService.getSeventhThing();
userService.seckill();
}
}
结果如下: