【每日一篇】AOP与注解与基于AOP的spring多数据源配置

    AOP也就是面向切面编程一向与IOC被称为是Spring的两大特性。作为依赖注入的补充,AOP使得我们能将每个方法都要调用的方法抽离出来形成一个单独的模块,降低了代码的耦合性,也降低了管理代码的难度。

     注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。作为JAVA WEB开发者,我们每天每一个方法都大量的使用了注解。但是正如上文所说,单纯的注解并没有任何作用,只能用来生成文档、标识功能。

    如果我们需要自定义一个注解,并且保证自定义的这个注解能发生作用,能改变我们的代码效果。那么我们就需要使用反射来追踪方法,处理这个注解,为他提供配套的操作。当然反射的使用的是非常麻烦的,而且在使用Spring进行开发时,已经提供了AOP这一工具使得我们可以为自定义注解提供配套的切面类,高效率低耦合的使用自定义注解。

    我们可以使用Spring AOP提供的@Pointcut标签轻松的获取所有需要处理的自定义注解类及方法,随后可以通过@Before,@After的方法为所有标记了该注解的类或类中的方法添加一层前置方法或者后置方法。以下是3个用于追踪注解的@PointCut表达式:

        1.@annotation 表示所有实现了注解的方法

       2.@target 表示所有实现了注解的对象中的方法

        3.@within 表示所有实现了注解的类中的方法

       比较典型的基于自定义注解及AOP的实践就是 基于AOP的spring多数据源配置了,有一个非常不错的文档,提供一下可以参考基于AOP的spring多数据源配置

        然后这个文档中的方法是配置到method级别的,实际使用中还是要每个方法都加注解,省点事的话可以配到类级别,这样又省了一点时间不是,方法如下:

@Aspect
@Component
@Order(1)
public class DynamicDataSourceAspect {



    @Before("@within(com.ucmed.util.dataSource.DynamicDataSourceAnnotation)") //前置通知
    public void simpleBefore(JoinPoint point){
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class);
        if (dataSourceAnnotation != null ) {
            //获得访问的方法名
            String methodName = point.getSignature().getName();
            //得到方法的参数的类型
            Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
            String dataSource = dataSourceAnnotation.dataSource();
            try {
                Method method = className.getMethod(methodName, argClass);
                if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) {
                    DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class);
                    dataSource = annotation.dataSource();
                    System.out.println("DataSource Aop ====> "+dataSource);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            DynamicDataSourceHolder.setDataSource(dataSource);
        }
    }

    @After("@annotation(com.ucmed.util.dataSource.DynamicDataSourceAnnotation)")   //后置通知
    public void simpleAfter(JoinPoint point){
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        DynamicDataSourceAnnotation dataSourceAnnotation = className.getAnnotation(DynamicDataSourceAnnotation.class);
        if (dataSourceAnnotation != null ) {
            //获得访问的方法名
            String methodName = point.getSignature().getName();
            //得到方法的参数的类型
            Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
            String dataSource = dataSourceAnnotation.dataSource();
            try {
                Method method = className.getMethod(methodName, argClass);
                if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) {
                    DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class);
                    dataSource = annotation.dataSource();
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(dataSource != null && !DynamicDataSourceHolder.MY_DATA_SOURCE.equals(dataSource)) DynamicDataSourceHolder.clearDataSource();
        }
    }




}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值