springboot捕獲全局異常和配置多數據源
捕獲全局異常是在項目運行期間如果調用的某一個方法出現了運行時異常,則會捕獲,並且給出回饋。
首先需要建一個包,包裏新建一個捕獲異常類GlobalExceptionHandler。前提是springboot的啓動類的掃描註解ComponentScan()要掃描到。
/**
* 用於捕獲全局異常
*/
@ControllerAdvice//控制器切面
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)//捕獲運行時異常
@ResponseBody
public Map<String,Object> exceptionHandler(){//處理異常方法
Map<String,Object> map=new HashMap<String, Object>();
map.put("errorCode","101");
map.put("errorMsg","系統錯誤!");
return map;
}
}
這個捕獲異常類可以捕獲到全局的運行時異常,例如商城購物車的控制層一個方法出現異常,黃色背景的是重點,會發生異常。
@RequestMapping("getShoppingCar")
public String getShoppingCar(HttpSession session,Model model){
Map<Integer,Cart> cartMap =(Map<Integer,Cart>)session.getAttribute("cartMap");
model.addAttribute("carList",cartMap);
int i=1/0;
return "udai_shopcart";
}
然後啓動項目,進入主頁,當點擊購物車按鈕時也就是調用了getShoppingCar這個方法,發生了異常,運行結果是跳轉頁面失敗,直接給出異常信息,也就是全局捕獲異常類中設置的信息。
配置多數據源
以前是在applicationContext.xml中配置的,現在springboot通過註解來配置數據源。
首先在application.properties配置文件中加入多數據源配置。
spring.datasource.test1.url=jdbc:mysql://127.0.0.1:3306/test1?serverTimezone=UTC
spring.datasource.test1.username=root
spring.datasource.test1.password=1234
spring.datasource.test1.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://127.0.0.1:3306/test2?serverTimezone=UTC
spring.datasource.test2.username=root
spring.datasource.test2.password=1234
spring.datasource.test2.driverClassName=com.mysql.cj.jdbc.Driver
在例子開始之前,首先去創建兩個用於測試的數據庫test1和test2,並且新建兩張空表。
寫兩個數據源的配置類。
在java文件夾下新建dataSource包,新建數據源配置類DataSource01和DataSource02。
@Configuration//註解到springboot容器中
@MapperScan(basePackages="com.gyf.test1.mapper",sqlSessionFactoryRef="test1SqlSessionFactory")
public class DataSource01 {
/**
* @return 返回test1數據庫的數據源
*/
@Bean(name="test1DataSource")
@Primary//主數據源,一個應用只能有一個主數據源
@ConfigurationProperties(prefix="spring.datasource.test1")
public DataSource dateSource(){
return DataSourceBuilder.create().build();
}
/**
* @return 返回test1數據庫的會話工廠
*/
@Bean(name = "test1SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("test1DataSource") DataSource ds) throws Exception{
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
return bean.getObject();
}
/**
* @return 返回test1數據庫的事務
*/
@Bean(name = "test1TransactionManager")
@Primary//主事務
public DataSourceTransactionManager transactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* @return 返回test1數據庫的會話模版
*/
@Bean(name = "test1SqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@Configuration//註解到springboot容器中
@MapperScan(basePackages="com.gyf.test2.mapper",sqlSessionFactoryRef="test2SqlSessionFactory")
public class DataSource02 {
/**
* @return 返回test2數據庫的數據源
*/
@Bean(name="test2DataSource")
@ConfigurationProperties(prefix="spring.datasource.test2")
public DataSource dateSource(){
return DataSourceBuilder.create().build();
}
/**
* @return 返回test2數據庫的會話工廠
*/
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("test2DataSource") DataSource ds) throws Exception{
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(ds);
return bean.getObject();
}
/**
* @return 返回test2數據庫的事務
*/
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* @return 返回test2數據庫的會話模版
*/
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
在java文件夾下分別創建兩個文件夾test1和test2,分別對這兩個數據庫進行操作,啓動類都需要先掃描到test1和test2的包
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.gyf.datasource","com.gyf.web","com.gyf.test1.service","com.gyf.test2.service"})
public class App
{
public static void main( String[] args )
{
//啓動springboot項目
SpringApplication.run(App.class,args);
}
}
Test1的userMapper
public interface UserMapper {
@Insert("insert user (username,password) values (#{username},#{password})")
public int save(@Param("username") String username, @Param("password") String password);
}
Test1的UserServiceImpl
@Service
@Transactional
public class UserServiceImpl{
@Autowired
private UserMapper userMapper;
public void register(String username, String password) {
userMapper.save(username,password);
}
}
Test2的CustomerMapper
public interface CustomerMapper {
@Insert("insert customer (name,tel) values (#{name},#{tel})")
public int save(@Param("name") String name, @Param("tel") String tel);
}
Test2的CustomerServiceImpl
@Service
@Transactional
public class CustomerServiceImpl {
@Autowired
private CustomerMapper customerMapper;
public void save(String name, String tel) {
customerMapper.save(name,tel);
}
}
最後寫一個controller類,調用這兩個service
@RestController //聲明Rest風格的控制器
//@EnableAutoConfiguration //自動配置,相當於寫了spring的配置文件
@RequestMapping("user")
public class UserController {
@Autowired
private UserServiceImpl userService;
@Autowired
private CustomerServiceImpl customerService;
@RequestMapping("register")
@ResponseBody
public String register(String username,String password){
//把數據保存到test1數據庫
userService.register(username,password);
//把數據保存到test2數據庫
customerService.save(username,"120");
return "success";
}
}
啓動項目,看數據庫表內容,兩張表都插入了信息。