控制反转和面向切面简单使用整理

1.使用注解实现ioc的配置

  1. 定义bean
  2. bean组件装配,依赖注入

2.面向切面(aop)

  1. 使用配置文件完成增强
  2. 使用注解完成增强

1.1 定义bean

<bean id=“xxx” class=“xx.xx.xxx” />

@Component("logger")
public class ServiceLogger {}

@Repository("userDao")
public interface UserDao {}

@Service("userService")
public class UserServiceImpl implements UserService{}

上面代码都完成定义bean,但使用特定的注解可以使组件的用户更加清晰
@Component 用于定义一些额外功能
@Repository 定义Dao层
@Service 定义业务实现

1.2 bean组件装配,依赖注入

/**
 * 按类型自动匹配合适的的衣领对象
 * 若没有匹配的bean则程序会抛出异常
 * 如果依赖不是必须的,设置@Autowired注解的required属性为false可以避免抛出异常
 */
@Autowired
private UserDao userDao;

/**
 * Dog类和Cat类继承Pet类,并且分别定义了bean
 * 这时通过@Autowired注入会查找到两个bean,程序不知道注入哪一个
 * 通过@Qualifier来指定名称注入就可以解决了
 */
@Autowired
private void queryPet(@Qualifier("dog") Pet pet){}

/**
 * 比较规范的注解注入
 * 通过naeme属性指定名称注入
 * 如果没有指定名称,则Resource会根据字段或setter方法产生的默认名称注入,没有找到这根据类型继续匹配
 * 字段默认名称字段名
 * setter方法默认名称是通过setter方法得到的属性名
 */
@Resource(name = "userDao")
private UserDao userDao;
 

2.1 使用配置文件完成增强

  • 配置文件
/**
 * 定义一个Bean
 */
<bean id="logger" class="cn.kgc.springtest2.demo1.logger.ServiceLogger"></bean>
<aop:config>
    /**
     * 切面,引用上方logger,用来当作增强类
     */
    <aop:aspect ref="logger">
    	/**
    	 * 定义切入点,expression为表达式,语法可以自己收集
    	 * 这里的意思是service包里面的所有类的所有方法都执行此增强
    	 */
        <aop:pointcut id="pointcut" expression="execution(* cn.kgc.springtest2.demo1.service..*(..))"></aop:pointcut>
        /**
         * 前置增强,目标方法执行前先执行logger里面定义的before()方法
         * method="方法名"
         * pointcut-ref="切点引用"
         */
        <aop:before method="before" pointcut-ref="pointcut"/>

	/**
         * 后置增强,目标方法正常执行完毕后执行logger里面定义的afterReturn()方法
         * 目标方法抛出异常则不会执行此方法
         */   
        <aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="result"></aop:after-returning>
        
        /**
         * 异常抛出增强,目标方法抛出异常时执行此方法,类似于catch代码块
         * throwing=""给目标方法参数赋值
         */
        <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>
        
        /**
         * 最终增强,类似于finally代码块,不管目标方法如何都会执行此after()方法
         */
        <aop:after method="after" pointcut-ref="pointcut"></aop:after>
        
        /**
         * 环绕增强,整合了其他增强
         */
        <aop:around method="around" pointcut-ref="pointcut"></aop:around>                              
    </aop:aspect>
</aop:config>
  • 增强类
public class ServiceLogger{
    /**
     * 后置增强
     * @param joinpoint 执行的方法
     * @param result 方法返回结果
     */
    public void afterReturn(JoinPoint joinpoint, Object result){
        log.info(joinpoint.getTarget()+"执行成功,返回信息是"+result);
    }

    /**
     * 前置增强
     */
    public void before(JoinPoint joinPoint){
        log.info(joinPoint.getSignature().getName()+"方法即将执行!");
    }
    
    /**
     * 异常增强
     * @param e 发生的异常实例
     */
    public void afterThrowing(RuntimeException e){
        log.error("我们检测到了报错情况,报错信息如下"+e.getMessage());
    }
    /**
     * 最终增强
     */
    public void after(){
        log.info("无论上面有没有报错我都会执行");
    }

    /**
     * 环绕增强
     * @param jp 执行的方法
     */
    public void around(ProceedingJoinPoint jp){
        try {
            //前置增强 方法执行之前
            log.info(jp.getSignature().getName()+"目标方法执行前......");
            //通知目标方法执行
            Object obj = jp.proceed();
            //后置增强 方法执行完毕  (程序发生异常不会执行此语句)
            log.info("方法执行完成,方法返回值是"+obj);
        } catch (Throwable throwable) {
            //异常增强 (程序异常时执行)
            log.error("啊报错了!信息是:"+throwable.getMessage());
            throwable.printStackTrace();
            //不执行finally代码块
            //System.exit(0);
        } finally {
            //最终增强
            log.info("我是最终增强!!!!!!");
        }
    }
}

2.2使用注解完成增强

  • 配置文件
<!--开启注解扫描-->
<context:component-scan base-package="cn.kgc"></context:component-scan>
<!--开启注解扫描,扫描切面,增强信息-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 增强类
/**
 * @Slf4j 事务
 * @Aspect 定义切面
 * @Component 定义Bean
 */
@Slf4j
@Aspect
@Component
public class ServiceLogger {

    /**
     * 定义切点
     */
    @Pointcut("execution(* cn.kgc.springtest2.demo1.service..*(..))")
    public void pointcut(){}

    /**
     * 通过@AfterThrowing注解定义异常增强
     * value 引用切点
     * throwing 给参数赋值
     */
    @AfterThrowing(value = "pointcut()",throwing = "e")
    public void afterThrowing(RuntimeException e){
        log.error("我们检测到了报错情况,报错信息如下"+e.getMessage());
    }
    /**
     *	通过@Before定义前置增强
     */
    @Before
    public void before(JoinPoint joinPoint){
    	log.info(joinPoint.getSignature().getName()+"方法即将执行!");
    }

    /**
     * 通过@AfterReturning注解定义后置增强
     * @param joinpoint 目标方法
     * @param result 返回结果
     */
    @AfterReturning(value = "pointcut()",returning = "result")
    public void afterReturn(JoinPoint joinpoint, Object result){
        log.info(joinpoint.getTarget()+"执行成功,返回信息是"+result);
    }
    
    /**
     * 通过@After定义最终增强
     */
    @After("pointcut()")
    public void after(){
        log.info("无论上面有没有报错我都会执行");
    }
   

    /**
     * 环绕增强
     * @param jp 执行的方法
     */
    @Around("pointcut()")
    public void around(ProceedingJoinPoint jp){
        try {
            //前置增强 方法执行之前
            log.info(jp.getSignature().getName()+"目标方法执行前......");
            //通知目标方法执行
            Object obj = jp.proceed();
            //后置增强 方法执行完毕  (程序发生异常不会执行此方法)
            log.info("方法执行完成,方法返回值是"+obj);
        } catch (Throwable throwable) {
            //异常增强 (程序异常时执行)
            log.error("啊报错了!信息是:"+throwable.getMessage());
            throwable.printStackTrace();
            //不执行finally代码块
            //System.exit(0);
        } finally {
            //最终增强
            log.info("我是最终增强!!!!!!");
        }
    }

上面只是写了简单的日志增强,还可以添加更复杂的代码来实现其他增强

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值