XML配置方
优点:便于阅读、与业务代码解耦
缺点:解析XML影响性能、开发工作量大,编译器不可校验配置正确性
注解配置方式
优点:开发便捷、编译期可校验配置正确性
缺点:注解与代码绑定,配置分散,不利于统一处理
Java配置方式
优点:编译期可校验配置正确性、配置简单,方便维护和管理、可以使用IDE的代码提示功能
缺点:不利于新人学习和理解框架的原理
实现Java配置的方式,主要通过两个注解:@Configuration和@Bean
@Configuration
标注于类上,表示该类为配置类,具有与Spring IoC配置文件相同的功能
@Bean
标注于配置类的方法上,用于向该配置类注入一个Bean组件
方法返回值为组件的对象类型
演示案例
实体类
public class Dog {
private String name;//宠物狗狗的姓名
private int age;//宠物狗狗的年龄
//此处省略getter and setter 方法
}
public class User {
private String userName;
private Dog dog;
//此处省略getter and setter 和 toString方法
}
配置类
/**
* @Configuration 指明当前类是一个配置类,就是来代替之前的Spring配置文件
* 在配置文件中用 标签添加组件
*/
@Configuration
public class JavaConfig {
//将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
//@Bean
//@Bean注解提供了name属性,通过name属性可以指定Bean组件的id值
@Bean(name = "user13")
public User user12(){
User user=new User();
user.setUserName("小明");
Dog dog=new Dog();
dog.setName("欢欢");
dog.setAge(5);
user.setDog(dog);
return user;
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest
class Ch041javapeizhiApplicationTests {
@Test
void contextLoads() {
/*java配置的方式生成的Spring容器。测试时,首先通过AnnotationConfigApplicationContext
获取SpringIoc容器的上下文信息。再在上下文信息中获取对应的Bean组件*/
ApplicationContext act=new AnnotationConfigApplicationContext(JavaConfig.class);
User user=(User)act.getBean("user13");
System.out.println(user.toString());
}
@Resource
private User user;
@Test
void contextLoads2() {
System.out.println(user.toString());
}
}
Java配置方式扩展
Bean组件的作用域:@Scope注解可以标注在方法上与@Bean注解搭配使用
@Scope("singleton") :默认,单例模式,容器只创建一次实例
@Scope("prototype") :每次获取时创建新的实例
initMethod属性
作用:被标注的方法将于容器启动前执行
使用方法:@Bean(initMethod="Bean中的初始化方法名")
destroyMethod属性
作用:被标注的方法将于容器销毁前执行
使用方法:@Bean(destroyMethod="Bean中的销毁方法名")
SpringBoot整合MyBatis的方式有两种,根据引入依赖的名称:分为mybatis-spring的方式 和 mybatis-spring-boot-starter的方式。
方式1:mybatis-spring方式
创建SpringBoot项目,搭建项目结构如图:
实体类----------------------------------------
public class User {
private Integer id;
private String userName;
private String userPassword;
//此处省略getter and setter
}
mapper类----------------------------------------
public interface UserMapper {
//根据id查询对应的用户信息
User getUserById(Long id);
}
mapper映射文件----------------------------------------
service接口----------------------------------------
public interface UserService {
//根据id查询对应的用户信息
User getUserById(Long id);
}
service接口实现类----------------------------------------
import javax.annotation.Resource;
@Service
public class UserServiceImpl implements UserService{
@Resource
private UserMapper userMapper;
//根据id查询对应的用户信息
@Override
public User getUserById(Long id) {
return userMapper.getUserById(id);
}
}
步骤1:引入依赖:MyBatis包、MyBatis-Spring整合包
org.mybatis
mybatis-spring
2.0.3
org.mybatis
mybatis
3.5.1
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc
步骤2:编写配置信息:配置数据源DataSource、配置SqlSessionFactoryBean、配置MapperScannerConfigurer
2.1配置数据源(这里在application.yml文件中配置的)
application.yml文件
#配置数据源DataSource
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull
username: root
password: 123456
2.2配置SqlSessionFactoryBean
新建工具类DataSourceUtil.java,类中添加如下代码
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DataSourceUtil {
@Autowired
private DataSource dataSource;
@Bean
public SqlSessionFactory sqlSessionFactoryBean(){
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
try {
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.msds.bean");
return sqlSessionFactoryBean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
}
2.3配置MapperScannerConfigurer
创建工具类MyBatisConf .java,类中添加如下代码
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConf {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
//定义扫描器实例
MapperScannerConfigurer msc=new MapperScannerConfigurer();
//通过SqlSessionFactoryBean生产SqlSessionFactory实例
//小括号中的信息来源于DataSourceUtil类中的获取SqlSessionFactory方法的名字
msc.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
//定义扫描的包
msc.setBasePackage("com.msds.mapper");
return msc;
}
}
完成了上述配置代码之后,就完成了与MyBatis的整合工作。在业务实现类中注入Mapper组件,并在UserController类中编写getUserById()方法,接受前台页面的请求,实现通过用户的id查询用户信息。UserController代码如下
import com.msds.bean.User;
import com.msds.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
//@RestController 此注解是一个组合注解,是Controller和@ResponseBody的组合
@RestController
public class UserController {
@Resource
private UserService userService;
@RequestMapping(value = "/getUserById",method = RequestMethod.GET)
public String getUserById(@RequestParam String id){
User user=userService.getUserById(Long.parseLong(id));
String name=user.getUserName();
return name;
}
}
方式2:mybatis-spring-boot-starter方式
步骤1:引入依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.1
mysql
mysql-connector-java
步骤2:编写配置文件
使用mybatis-spring-boot-starter的方式整合时,SpringBoot已经通过自动配置,生成了系统所需要的MapperScannerConfigurer组件,并给此组件注入了DataSource,开发人员需要在application.yml文件中配置数据源,指定mapper映射文件和接口的位置、MyBatis配置文件的位置和需要起别名的实体所在包的位置。具体配置如下:
#配置数据源DataSource
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull
username: root
password: 123456
mybatis:
#指定Mapper映射文件位置
#mapper-locations: classpath:com/msds/mapper/UserMapper.xml
mapper-locations: classpath:com/msds/mapper/*.xml
#指定需起别名的实体包位置
type-aliases-package: com.msds.bean
步骤3:步骤2的配置中缺少了指定Mapper接口位置的配置,MyBatis中提供了两个注解,用于指定Mapper接口的位置
@Mapper:标注在Mapper接口上
@MapperScan("Mapper接口所在的包名"):标注到启动类上,或者某个配置类上(即被@Configuration标注的类)
使用以上两个注解中的任何一个都可指定Mapper的接口位置代码测试
演示案例:配置DBCP2连接池
步骤1:添加依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.0.1
mysql
mysql-connector-java
org.apache.commons
commons-dbcp2
步骤2:在application.yml中配置DBCP2数据源连接池
#配置数据源DataSource
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=convertToNull
username: root
password: 123456
#数据源的类型。使用DBCP2配置连接池,需指定数据源类型,否则Spring Boot仍会使用内置的数据源
type: org.apache.commons.dbcp2.BasicDataSource
dbcp2:
#最大空闲数
max-idle: 10
#最大连接数
max-total: 50
mybatis:
#指定Mapper映射文件位置
#mapper-locations: classpath:com/msds/mapper/UserMapper.xml
mapper-locations: classpath:com/msds/mapper/*.xml
#指定需起别名的实体包位置
type-aliases-package: com.msds.bean
步骤3:启动类上要添加注解
@MapperScan("Mapper接口所在的包名")
步骤4:测试——编写DataSourceShow类,如下:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
//项目在启动时就可加载 重写的setApplicationContext()方法
@Component
public class DataSourceShow implements ApplicationContextAware {
ApplicationContext ac=null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ac=applicationContext;
DataSource dataSource=applicationContext.getBean(DataSource.class);
System.out.println("+++++++++++++++++++++++++++++++++++++++");
System.out.println(dataSource.getClass().getName());
}
}
事务控制
SpringBoot项目中可以使用注解管理事务——@Transactional
添加到类上,作用于当前类的所有方法
添加到方法上,作用于当前方法
在实际的开发中可能配置多数据源,针对不同的数据源,SpringBoot生成的事务管理器也不同。此时可以通过@Transactional的Value属性指定使用的事务管理器
@Transactional(Value="事务管理器的名称")
扩展知识
设置事务传播特性
@Transactional(isolation=Isolation.PROPAGATION_REQUIRED)
默认:REQUIRED
设置事务隔离级别
@Transactional(propagation=Propagation.ISOLATION_DEFAULT)
默认:使用数据库的隔离级别
windows下安装Redis/菜鸟教程:Redis 安装 | 菜鸟教程
步骤1:引入依赖
org.springframework.boot
spring-boot-starter-data-redis
步骤2:配置Redis连接
由于SpringBoot整合Redis之后内部已经集成了与Redis相关的自动配置,所以,开发人员只需在application.yml文件中配置与Redis服务端的连接,需要配置的内容如下:
spring:
redis:
host: Redis服务的IP 本机的话写127.0.0.1或localhost就可以了
port: Redis服务端口,通常为 6379
password: 连接Redis服务的密码 无密码就啥都不写
database: 0 "0"表示0号库
步骤3:创建RedisTemplate的Bean组件
RedisTemplate是SpringBoot提供的一个模板类,它提供了很多快速使用Redis的API,而不需要自己来维护连接、事务。
具体实现方法是创建一个配置类来管理RedisTemplate的Bean组件,具体代码实现如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class RedisConfig {
//参数RedisConnectionFactory为Spring Boot自动注入
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
RedisTemplate rt=new RedisTemplate();
rt.setConnectionFactory(factory);
return rt;
}
}
步骤4:创建工具类调用RedisTemplate操作Redis服务端,进行数据的存取。代码如下
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class RedisUtil {
@Resource
private RedisTemplate redisTemplate;
/**
* 往redis中缓存数据
* @param key
* @param object
* @return
*/
public boolean set(String key,Object object){
ValueOperations vo=redisTemplate.opsForValue();
vo.set(key,object);
return true;
}
/**
* 根据key从redis服务器中获取value值
* @param key
* @return
*/
public Object get(String key){
ValueOperations vo=redisTemplate.opsForValue();
return vo.get(key);
}
}
步骤5:测试
首先需要在项目启动时为Redis初始化一些数据。SpringBoot提供了一个名为CommandLineRunner的接口。实现了此接口的类,重写CommandLineRunner接口的run()方法,run()方法中的代码即可在项目启动时运行。
这里通过创建CommandLineRunner的子类来完成Redis数据的初始化工作,代码如下:
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class MyRunner implements CommandLineRunner {
@Resource
private RedisUtil redisUtil;
@Override
public void run(String... args) throws Exception {
System.out.println("项目启动了。。。");
redisUtil.set("key02","spring-redis");
System.out.println("获取redis中的值:"+redisUtil.get("key02"));
}
}
我们现在使用springBoot默认提供的redis服务,但是按上面的步骤操作完以后。
发现存在的问题:序列化,我们set到redis服务器中的key和value是这样的
解决这个问题就需要将key和value序列化,如果是xml配置的
我们直接注入官方给定的keySerializer,valueSerializer,hashKeySerializer即可:
那么使用注解的话我们需要自己在自己编写的配置中将key、value进行转换
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
//参数RedisConnectionFactory为Spring Boot自动注入
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory){
RedisTemplate rt=new RedisTemplate();
rt.setConnectionFactory(factory);
//默认存储的是二进制 以下是转成String的
rt.setKeySerializer(new StringRedisSerializer());
rt.setValueSerializer(new StringRedisSerializer());
return rt;
}
}