【笔记】AOP对原有功能进行增强

AOP

概念:面向切面编程

作用:在不改动原代码的情况下对其功能进行增强

核心概念

连接点:所有正在运行的方法都是连接点(连接点包含切入点)

切入点:需要进行增强的连接点

切面:描述通知与切入点的对应关系

通知:增强的操作,也就是切入点需要进行增强的功能

通知类:通知方法所在的类

操作步骤

导入aop坐标,spring中会将aop传递过来

  <!--spring核心依赖,会将spring-aop传递进来-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <!--切入点表达式依赖,目的是找到切入点方法,也就是找到要增强的方法-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

定义接口和实现类

public interface AopService {
    void save();
}


@Service
public class AopServiceImpl implements AopService {
    public void save() {
        System.out.println("AopServiceImpl...");
    }
}

定义aop通知类

@Component//通知类配置成配Spring管理的Bean
@Aspect//设置当前类为切面类
public class SpringAop {

    @Pointcut("execution(void com.cyf.service.impl.AopServiceImpl.save())")//定义切入点
    public void pt(){}

    @Before("pt()")//将切入点和通知连接
    public void method(){
        System.out.println("SpringAop...");
    }
}

定义配置类

@Configuration
@ComponentScan("com.cyf")
@EnableAspectJAutoProxy//开启aop
public class SpringConfig {
}

AOP的底层是动态代理

IOC容器中的对象,不再是原来的实现类对象,而是产生新的对象,在我们获取对象的时候,只能用接口类型

AOP通知类型

前置通知

在原代码执行前执行代码

 @Before("pt()")//将切入点和通知连接
    //前置通知,在执行原方法前执行
    public void Before(){
        System.out.println("SpringAop...Before");
    }

后置通知

在源代码执行后执行代码

    @After("pt()")
    //后置通知,在执行原方法后执行
    public void after(){
        System.out.println("SpringAop...After");
    }

环绕通知

增强的功能包裹原方法

    /**
     *  //环绕通知,将增强的功能包裹原方法
     * @param pjp 切入点的对象,通过对象执行切入点代码
     * @return
     * @throws Throwable
     */
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("SpringAop...AroundBefore");
        pjp.proceed();
        System.out.println("SpringAop...AfterBefore");
        return 200;
    }

返回后通知

在正常运行后执行的方法

   @AfterReturning("pt()")
    //返回后通知,正常运行后执行的方法
    public void afterreturning(){
        System.out.println("SpringAop...AfterReturning");
    }

抛出异常后通知

在抛出异常后执行

    @AfterThrowing("pt()")
    //抛出异常后通知,在出现异常后执行
    public void afterthrowing(){
        System.out.println("SpringAop...AfterThrowing");
    }

数据获取

参数获取

除Around外,其他通知获取参数

 @Before("pt()")
 @After("pt()")
 @AfterReturning("pt()")
 @AfterThrowing("pt()")
    public void Before(JoinPoint jp){
       jp.getArgs(); //获取参数
    }

Around通知获取参数

    /**
     *  //环绕通知,将增强的功能包裹原方法
     * @param pjp 切入点的对象,通过对象执行切入点代码
     * @return
     * @throws Throwable
     */
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
		pjp.getArgs();//获取参数
    }

返回值获取

只有两个通知可以获取参数

Around获取参数

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {    // 手动调用连接点方法,返回值就是连接点方法的返回值    
  Object ret = pjp.proceed();   
  return ret;
}

AfterReturning获取参数

@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(String ret) { 
    //变量名要和returning="ret"的属性值一致
    System.out.println("afterReturning advice ..."+ret);
}

获取异常

AfterThrowing异常

@AfterThrowing(value = "pt()",throwing = "t")
public void afterThrowing(Throwable t) {
    //变量名要和throwing = "t"的属性值一致
    System.out.println("afterThrowing advice ..."+ t);
}

Around获取异常

@Around("pt()")
public Object around(ProceedingJoinPoint pjp)  {
    Object ret = null;
    //此处需要try...catch处理,catch中捕获到的异常就是连接点方法中抛出的异常
    try {
        ret = pjp.proceed();
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return ret;
}

instanceof比较

  • instanceof关键字用来对比左边的对象是否属于右边的对象
  • instanceof的左右两边必须是引用类型,java 八大基本数据类型无法使用 instanceof来进行对比
  • instanceof用来判定左边的引用类型是否与右边的引用类型的类型是否相同,或左边引用类型是右边引用类型的子类或实现类(右边引用类型可以是类、抽象类、接口)
  • null与任何引用类型进行 instanceof对比的结果都是 false,null不属于任何类型,更不属于 object基类的派生类(子类),需要特别注意

比较数据类型也可以用字节码进行对比,精确度100%

通过getClass的方法和String.class进行对比,比较数据类型

trim用于删除字符串头尾的空白符

Spring事务配置

步骤:

1.配置事务管理器

//配置事务管理器,mybatis使用的是jdbc事务
//需要在jdbc管理器中配置
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    return new DataSourceTransactionManager(dataSource);
}

2.开启注释事务驱动

@Configuration
@ComponentScan("com.cyf")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class,MybatiesConfig.class})
@EnableTransactionManagement//开启事务驱动
public class SpringConfig {
}

3.在业务层接口中添加事务管理

public interface AccountService {

    @Transactional//添加事务管理
    void transfer(String out,String in ,Double money);
}

事务添加到方法上表示当前方法开启事务,如果添加在整个接口上表示接口中所有方法开启事务

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值