基于注解的 AOP 配置

基于注解的 AOP 配置

	1: 配置 pom.xml
		<dependencies>
	        <dependency>
	            <groupId>org.springframework</groupId>
	            <artifactId>spring-context</artifactId>
	            <version>5.0.2.RELEASE</version>
	        </dependency>

	        <dependency>
	            <groupId>org.aspectj</groupId>
	            <artifactId>aspectjweaver</artifactId>
	            <version>1.8.7</version>
	        </dependency>
	    </dependencies>
	2: 定义账户的业务层接口
		public interface IAccountService {
		    /**
		     * 模拟保存账户
		     */
		   void saveAccount();

		    /**
		     * 模拟更新账户
		     * @param i
		     */
		   void updateAccount(int i);

		    /**
		     * 删除账户
		     * @return
		     */
		   int  deleteAccount();
		}
	3: 定义账户的业务层实现类
		@Service("accountService")
		public class AccountServiceImpl implements IAccountService{

		    @Override
		    public void saveAccount() {
		        System.out.println("执行了保存");
		        int i=1/0;
		    }

		    @Override
		    public void updateAccount(int i) {
		        System.out.println("执行了更新"+i);

		    }

		    @Override
		    public int deleteAccount() {
		        System.out.println("执行了删除");
		        return 0;
		    }
		}
	4: 用于记录日志的工具类,它里面提供了公共的代码
		import org.aspectj.lang.ProceedingJoinPoint;
		import org.aspectj.lang.annotation.*;
		import org.springframework.stereotype.Component;

		/**
		 * 用于记录日志的工具类,它里面提供了公共的代码
		 */
		@Component("logger")
		@Aspect//表示当前类是一个切面类
		public class Logger {

		    @Pointcut("execution(* com.demos.service.impl.*.*(..))")
		    private void pt1(){}

		    /**
		     * 前置通知
		     */
		    @Before("pt1()")
		    public  void beforePrintLog(){
		        System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。");
		    }

		    /**
		     * 后置通知
		     */
		   @AfterReturning("pt1()")
		    public  void afterReturningPrintLog(){
		        System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。");
		    }
		    /**
		     * 异常通知
		     */
		    @AfterThrowing("pt1()")
		    public  void afterThrowingPrintLog(){
		        System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。");
		    }

		    /**
		     * 最终通知
		     */
		    @After("pt1()")
		    public  void afterPrintLog(){
		        System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。");
		    }

		    @Around("pt1()")
		    public Object aroundPringLog(ProceedingJoinPoint pjp){
		        Object rtValue = null;
		        try{
		            Object[] args = pjp.getArgs();//得到方法执行所需的参数

		            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。前置");

		            rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)

		            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。后置");

		            return rtValue;
		        }catch (Throwable t){
		            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。异常");
		            throw new RuntimeException(t);
		        }finally {
		            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。最终");
		        }
		    }
		}
	5: bean.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/aop
		        http://www.springframework.org/schema/aop/spring-aop.xsd
		        http://www.springframework.org/schema/context
		        http://www.springframework.org/schema/context/spring-context.xsd">

		    <!-- 配置spring创建容器时要扫描的包-->
		    <context:component-scan base-package="com.itheima"></context:component-scan>

		    <!-- 配置spring开启注解AOP的支持 -->
		    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
		</beans>

		如果不使用xml文件的话
			@Configuration
			@ComponentScan(basePackages="com.demos") //扫描容器的包
			@EnableAspectJAutoProxy   				 //开启注解AOP支持
			public class SpringConfiguration {
			}
	6: 综合案例
		* UserService.java
			package com.demos.aop_anno;

			public interface UserService {
			   public void save(String name,int id);
			   public String getById(int id);
			}
		* UserServiceImpl.java
			package com.demos.aop_anno;

			import org.springframework.stereotype.Service;

			@Service
			public class UserServiceImpl implements UserService {

				@Override
				public void save(String name,int id) {
					// TODO Auto-generated method stub
			        System.out.println("保存用户。。。");
			        //int i=1/0;
				}

				@Override
				public String getById(int id) {
					// TODO Auto-generated method stub
					System.out.println("根据主键获取用户。。。");
					return "小强";
				}
			}
		* ServiceProxy.java
			package com.demos.aop_anno;

			import org.aspectj.lang.JoinPoint;
			import org.aspectj.lang.ProceedingJoinPoint;
			import org.aspectj.lang.annotation.Around;
			import org.aspectj.lang.annotation.Aspect;
			import org.aspectj.lang.annotation.Before;
			import org.springframework.stereotype.Component;

			//代理类
			@Component//组件
			@Aspect//声明当前类是切面类
			public class ServiceProxy {
				
				//JoinPoint封装了目标类中方法的特性(方法名,参数等。)
				//@AfterThrowing(execution( * com.demos.aop_anno.*.*(..))",throwing="exp")
				@Before(value="execution( * com.demos.aop_anno.*.*(..))")
				public void toStrong(JoinPoint jp/*,Object res*//*,Throwable exp*/) {
					//目标类的中切点的参数
					String methodname = jp.getSignature().getName();
					System.out.println("目标方法名:"+methodname);
					if ("save".equals(methodname)) {
						Object[] args = jp.getArgs();
						for (Object o : args) {
							System.out.println("目标方法的参数:"+o);
						}
						System.out.println("增强的内容。。。");
					}
				}
				
				//环绕通知
				@Around(value="execution(* com.demos.aop_anno.*.*(..))")
				public void toStrong1(ProceedingJoinPoint jp) {
					//目标类的中切点的参数
					String methodname = jp.getSignature().getName();
					System.out.println("目标方法名11:"+methodname);
					if ("save".equals(methodname)) {
						Object[] args = jp.getArgs();
						for (Object o : args) {
							System.out.println("目标方法的参数11:"+o);
						}
						System.out.println("增强的内容11。。。");
					}
					System.out.println("开启事务");
					try {
						jp.proceed();//调用目标方法
					}catch (Throwable e) {
						e.printStackTrace();
					}
					System.out.println("提交事务");
				}
			}
		* beans.xml
			<?xml version="1.0" encoding="UTF-8"?>
			<beans xmlns="http://www.springframework.org/schema/beans"
			       xmlns:context="http://www.springframework.org/schema/context"
			       xmlns:aop="http://www.springframework.org/schema/aop"
				   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
				         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.xsd"
			                                 >
			    <!-- 开启注解扫描包 -->
				<context:component-scan base-package="com.demos.aop_anno"></context:component-scan>
				<!-- 启用AOP自动代理 -->
				<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
			</beans>
		* ProxyTest.java
			package com.demos.aop_anno;

			import org.springframework.context.ApplicationContext;
			import org.springframework.context.support.ClassPathXmlApplicationContext;

			public class ProxyTest {
				public static void main(String[] args) {
					ApplicationContext ap= new ClassPathXmlApplicationContext("com/demos/aop_anno/beans.xml");
					UserService us = ap.getBean("userServiceImpl",UserService.class);
					us.save("来来来",888);
					System.out.println("=====================================");
					us.getById(1);
				}
			}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值