【增强】(注解)SSM之配置多数据源

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zt_fucker/article/details/73849176

上篇是非注解的形式,每次切换数据源比较麻烦,于是就有了注解篇。
非注解地址:http://blog.csdn.net/zt_fucker/article/details/73848742

首先随便打开一个注解的源码:@Service为例

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any
     */
    String value() default "";

}

@Target为注解执行的目标地址,没有查阅资料,自己总结的(欢迎指正)

ElementType.TYPE:执行的位置是在类或接口上。如果挂在方法和参数上会出现错误;
The annotation @Service is disallowed for this location

ElementType.METHOD:执行的位置是在方法上,同理挂在类或接口上会出现上述错误。

PARAMETER.PARAMETER :执行的位置是在参数上,例如典型的@Param就是挂在参数上的。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {
  String value();
}

@Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:
RetentionPolicy.SOURCE :这种类型的Annotations只在源代码级别保留,编译时就会被忽略
RetentionPolicy.CLASS : 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
RetentionPolicy.RUNTIME : 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用.

然后编写我们自己的注解:

package com.guide.datasource;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.TYPE,ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) 
public @interface DataSource {
    String value();
}

通过AOP来捕获并实现@DataSource注解。

spring_mybatis.xml

<bean id="dataSourceAspect" class="com.guide.datasource.DataSourceAspect" />
<aop:config>
        <aop:aspect ref="dataSourceAspect">
            <!-- 拦截所有service方法 -->
            <aop:pointcut id="dataSourcePointcut" expression="execution(* com.guide.service..*.*(..))" />
            <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
        </aop:aspect>
    </aop:config>

DataSourceAspect .java

扫描二维码关注公众号,回复: 3852549 查看本文章
package com.guide.datasource;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

public class DataSourceAspect {

    /**
     * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
     * 
     * @param point
     * @throws Exception
     */
    public void intercept(JoinPoint point) throws Exception {
        Class<?> target = point.getTarget().getClass();
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
        for (Class<?> clazz : target.getInterfaces()) {
            resolveDataSource(clazz, signature.getMethod());
        }
        resolveDataSource(target, signature.getMethod());
    }

    /**
     * 提取目标对象方法注解和类型注解中的数据源标识
     * 
     * @param clazz
     * @param method
     */
    private void resolveDataSource(Class<?> clazz, Method method) {
        try {
            Class<?>[] types = method.getParameterTypes();
            // 默认使用类型注解
            if (clazz.isAnnotationPresent(DataSource.class)) {
                DataSource source = clazz.getAnnotation(DataSource.class);
                DynamicDataSourceHolder.setDataSource(source.value());
            }
            // 方法注解可以覆盖类型注解
            Method m = clazz.getMethod(method.getName(), types);
            if (m != null && m.isAnnotationPresent(DataSource.class)) {
                DataSource source = m.getAnnotation(DataSource.class);
                DynamicDataSourceHolder.setDataSource(source.value());
            }
        } catch (Exception e) {
            System.out.println(clazz + ":" + e.getMessage());
        }
    }
}

最后在service层中使用:

    @DataSource("dataSource01")
    public TUser query_ceshi() {
        // TODO Auto-generated method stub
        return tUSerMapper.query_ceshi();
    }

OK

猜你喜欢

转载自blog.csdn.net/zt_fucker/article/details/73849176