首页 > 其他分享 >aop+自定义注解实现数据源切换

aop+自定义注解实现数据源切换

时间:2023-03-12 09:34:31浏览次数:48  
标签:自定义 数据源 aop springframework dynamicdatasource org import com xt

pom.xml依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xt</groupId>
    <artifactId>dynamicDataSource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>dynamicDataSource</name>
    <description>dynamicDataSource</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>5.0.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.10</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml配置双数据源

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    yeb:
      url: jdbc:mysql://localhost:3306/yeb?serverTimezone=Asia/Shanghai
      username: root
      password: root
      druid:
        initial-size: 1
        min-idle: 1
        max-active: 20
        test-on-borrow: true
        driver-class-name: com.mysql.cj.jdbc.Driver
    mall:
      url: jdbc:mysql://localhost:3306/mall?serverTimezone=Asia/Shanghai
      username: root
      password: root
      druid:
        initial-size: 1
        min-idle: 1
        max-active: 20
        test-on-borrow: true
        driver-class-name: com.mysql.cj.jdbc.Driver

数据库

 

 

 

 

 

 

自定义配置类,绑定配置文件属性

DataSourceConfig

package com.xt.dynamicdatasource.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;


import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.yeb")
    public DataSource dataSource1(){
        //底层会自动拿到spring.datasource中的配置,创建一个DruidDataSource
       return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.mall")
    public DataSource dataSource2(){
        //底层会自动拿到spring.datasource中的配置,创建一个DruidDataSource
        return DruidDataSourceBuilder.create().build();
    }
}

自定义数据源

DynamicDataSource

package com.xt.dynamicdatasource.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Component
@Primary//将该Bean设置为主要注入Bean
public class DynamicDataSource extends AbstractRoutingDataSource {

    //当前使用的数据源标识
    public static ThreadLocal<String> name = new ThreadLocal<>();

    @Autowired
    DataSource dataSource1;
    @Autowired
    DataSource dataSource2;

    //返回当前数据源标识
    @Override
    protected Object determineCurrentLookupKey() {

        return name.get();
    }

    @Override
    public void afterPropertiesSet() {
        //为targetDataSources初始化所有的数据源
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("yeb",dataSource1);
        targetDataSources.put("mall",dataSource2);
        super.setTargetDataSources(targetDataSources);

        //为defaultTargetDataSource设置默认的数据源
        super.setDefaultTargetDataSource(dataSource1);
        super.afterPropertiesSet();
    }
}

自定义注解

SwitchDB

package com.xt.dynamicdatasource.annotation;

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 SwitchDB {
    String value() default "yeb"; //默认yeb数据库
}

aop切面

package com.xt.dynamicdatasource.aspect;

import com.xt.dynamicdatasource.annotation.SwitchDB;
import com.xt.dynamicdatasource.config.DynamicDataSource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class DynamicDataSourceAspect {
    //前置通知com.xt.dynamicdatasource.service.impl下面的所有类的注解都会进行增强
    @Before("within(com.xt.dynamicdatasource.service.impl.*) && @annotation(switchDB)")
    public void before(JoinPoint point, SwitchDB switchDB){
        String name = switchDB.value();
        DynamicDataSource.name.set(name);
        System.out.println(name);
    }
}

 

在实现类上使用@SwitchDB 注解

package com.xt.dynamicdatasource.service.impl;

import com.xt.dynamicdatasource.annotation.SwitchDB;
import com.xt.dynamicdatasource.entity.User;
import com.xt.dynamicdatasource.mapper.UserMapper;
import com.xt.dynamicdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    @SwitchDB("yeb")//访问yeb数据库
    public User getUsers() {
        User users = userMapper.getUsers();
        return users;
    }

    @Override
    @SwitchDB("mall")//访问mall数据库
    public Map<String, Object> getMenu() {
        Map<String, Object> menu = userMapper.getMenu();
        return menu;
    }


}

 

其他代码部分

UserController

package com.xt.dynamicdatasource.controller;

import com.xt.dynamicdatasource.annotation.SwitchDB;
import com.xt.dynamicdatasource.config.DynamicDataSource;
import com.xt.dynamicdatasource.entity.User;
import com.xt.dynamicdatasource.mapper.UserMapper;
import com.xt.dynamicdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;

@RestController
public class UserController {
    @Autowired
    UserService userService;

    @GetMapping("getUser")
    public User getUser(){
        User users = userService.getUsers();
        return users;
    }

    @GetMapping("getMenu")
    public Map getMenu(){
        Map<String, Object> menu = userService.getMenu();
        return menu;
    }
}

UserService

package com.xt.dynamicdatasource.service;

import com.xt.dynamicdatasource.entity.User;
import com.xt.dynamicdatasource.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;


public interface UserService {

    public User getUsers();

    Map<String, Object>  getMenu();
}

UserServiceImpl

package com.xt.dynamicdatasource.service.impl;

import com.xt.dynamicdatasource.annotation.SwitchDB;
import com.xt.dynamicdatasource.entity.User;
import com.xt.dynamicdatasource.mapper.UserMapper;
import com.xt.dynamicdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;

    @Override
    @SwitchDB("yeb")//访问yeb数据库
    public User getUsers() {
        User users = userMapper.getUsers();
        return users;
    }

    @Override
    @SwitchDB("mall")//访问mall数据库
    public Map<String, Object> getMenu() {
        Map<String, Object> menu = userMapper.getMenu();
        return menu;
    }


}

UserMapper

package com.xt.dynamicdatasource.mapper;

import com.xt.dynamicdatasource.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.Map;

@Mapper
public interface UserMapper {

    @Select("select * from t_user where id = 2")
    User getUsers();

    @Select("select * from t_menu where id = 7")
    Map<String,Object> getMenu();
}

启动类DynamicDataSourceApplication

package com.xt.dynamicdatasource;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@MapperScan(basePackages = "com.xt.dynamicdatasource.mapper")
@EnableAspectJAutoProxy//启动aop
public class DynamicDataSourceApplication {

    public static void main(String[] args) {
        SpringApplication.run(DynamicDataSourceApplication.class, args);
    }

}

 

标签:自定义,数据源,aop,springframework,dynamicdatasource,org,import,com,xt
From: https://www.cnblogs.com/ixtao/p/17207610.html

相关文章

  • Prometheus-pushgateway自定义监控项
    目录一、前言二、pushgateway安装三、pushgateway的使用四、pushgateway脚本思路一、前言pushgateway相比较exporter是主动向服务器发送请求,pushgateway本身也是一个程序......
  • 为application.yml创建自定义配置并进行自动提示
    第一步:导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>......
  • vue 自定义组件 实现v-model双向绑定
    父组件:<childCompv-model="aaa"/><script>...data(){return{aaa:123}}...</script>自定义组件:childComp.vue<script>...props:......
  • 自定义返回接口类型
    ResponseResultpackagecom.mao.common;publicclassR<T>{//状态码IntegerresultCode;//具体结果Tresult;//响应的信息Stringre......
  • 自定义控件 QOpenGLWidget并实现缩放(纯代码)
    QScrollArea+QOpenGLWidget实现缩放,用于显示QImage。先自定义QOpenGLWidget,然后自定义QWidget(上图)glwidget.h#ifndefGLWIDGET_H#defineGLWIDGET_H#include<QO......
  • ORACLE自定义实现FIND_IN_SET函数
    FIND_IN_SET是mysql中的函数,见:MySQL中FIND_IN_SET函数oracle中没有FIND_IN_SET函数,oracle自定义实现FIND_IN_SET函数sql如下:--FIND_IN_SET函数CREATEORREPLACEFUN......
  • java自定义类数组的初始化
    也就是说,在声明了自定义类的数组之后,对每一个数组元素的初始化,都要为其new一个对象出来使得指针指向该对象,Java语言本身是不提供在自定义类数组声明时候自动创建新对象的方......
  • Spring-AOP工作流程
    Spring-AOP工作流程3,AOP工作流程3.1AOP工作流程由于AOP是基于Spring容器管理的bean做的增强,所以整个工作过程需要从Spring加载bean说起:流程1:Spring容器启动容器启......
  • java自定义注解实现字段格式化(二)
    上篇java自定义注解实现字段格式化 我们自定义了另一个浮点数格式化的注解一、格式化处理器接口但在实际生产中,处理浮点数的格式化,可能还会有其他数据的格式化,比如日期......
  • LayoutAnimationController,补间动画,属性动画,值动画,自定义动画,帧动画
    最好的代码永远是自己写出来的布局<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools......