一、IOC/DI配置管理第三方bean(以数据库连接池为例)
第一步:导入相关的数据源配置信息
com.alibaba
druid
1.1.16
c3p0
c3p0
0.9.1.2
mysql
mysql-connector-java
5.1.47
**第二步:配置第三方bean**
说明:
driverClassName:数据库驱动
url:数据库连接地址
username:数据库连接用户名
password:数据库连接密码
二、加载properties文件
两个数据源中都使用到了一些固定的常量如数据库连接四要素,把这些值写在Spring的配置文件中不利于后期维护
需要将这些值提取到一个外部的properties配置文件中
Spring框架如何从配置文件中读取属性值来配置就是接下来要解决的问题。
第三方bean属性优化
1 引入context命名空间(5次更改,加入context)
2 使用context空间加载properties文件
3 引入属性占位符
说明:
.properties代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准。标准的写法,classpath:代表的是从根路径下开始查找,但是只能查询当前项目的根
路径。classpath:* :*.properties不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件。
三 核心容器
如何创建容器?
创建好容器后,如何从容器中获取bean对象?
容器类的层次结构是什么?
BeanFactory是什么?
容器加载方式:
// 1 加载类路径下的的配置文件
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
// 2 从文件系统下加载配置文件
ApplicationContext context1=new FileSystemXmlApplicationContext("C:\Users\jiang\IdeaProjects\Spring\src\main\resources\applicationContext.xml");
Bean三种方式的获取:
// 方式1
BookDao bookDao=(BookDao) context.getBean("bookDao");
// 方式2
BookDao bookDao=context.getBean("bookDao",BookDao.class);
// 方式3 按照类型进行查找
BookDao bookDao=context.getBean(BookDao.class);
继承关系:
四、核心容器总结
1、容器相关
BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
ApplicationContext接口提供基础的bean *** 作相关方法,通过其他接口扩展其功能
ApplicationContext接口常用初始化类
ClassPathXmlApplicationContext(常用)
FileSystemXmlApplicationContext
2、Bean相关
3、 依赖注入相关
五、注解开发
1、sing2.5注解开发定义Bean
使用@Component定义bean
@Component("bookDao")
public class BookDaoImpl implements BookDao {
`
核心配置文件中通过组件扫描加载bean
base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
包路径越多[如:com.itheima.dao.impl],扫描的范围越小速度越快
包路径越少[如:com.itheima],扫描的范围越大速度越慢
一般扫描到项目的组织名称即Maven的groupId下[如:com.itheima]即可
衍生注解:
@Controller、@Service、@Repository
在编写类的时候能很好的区分出这个类是属于表现层、业务层还是数据层的类
2、sping3纯注解开发
Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道
实现思路:
将配置文件applicationContext.xml删除掉,使用类来替换
实现过程:
替换为:
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
加载方式的不同:
方式1:
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = context.getBean(BookDao.class);
bookDao.save();
BookService bookService = context.getBean(BookService.class);
bookService.save();
方式2:纯注解开发
ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = context.getBean(BookDao.class);
bookDao.save();
BookService bookService = context.getBean(BookService.class);
bookService.save();
总结:
六 注解开发下的bean管理
bean作用范围(单例还是多例)
bean生命周期
@PostConstruct //记忆:在构造方法后执行
public void init(){
System.out.println("init。。。");
}
@PreDestroy //记忆:在销毁之前运行
public void destroy(){
System.out.println("destroy。。。");
}
自动装配
Spring为了使用注解简化开发,并没有提供构造函数注入、setter注入对应的注解,只提供了自动装配的注解实现。
@Autowired可以写在属性上,也可也写在setter方法上,最简单的处理方式是写在属性上并将 setter方法删除掉
为什么setter方法可以删除呢?
自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值,普通反射只能获取public修饰的内容。暴力反射除了获取public修饰的内容还可以获取private修改的内容,所以此处无需提供setter方法
使用@Value可以进行简单数据类型的注入
public class BookDaoImpl implements BookDao {
@Value("itheima")
private String name;}
@Value一般会被用在从properties配置文件中读取内容进行使用
加载properties文件,使用注解@PropertySource({“classpath:jdbc.properties”})****
@Configuration
@ComponentScan("com.itheima")
@PropertySource({"classpath:jdbc.properties"})
public class SpringConfig {
}
注解总结:
IOC/DI注解开发管理第三方bean
前面定义bean的时候都是在自己开发的类上面写个注解就完成了,但如果是第三方的类,这些类都是在jar包中,我们没有办法在类上面添加注解,这个时候该怎么办?
遇到上述问题,需要有一种更加灵活的方式来定义bean,这种方式不能在原始代码上面书写注解,一样能定义bean,这就用到了一个全新的注解@Bean。
@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象
@Configuration
public class SpringConfig
{ @Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds; } }
注意:不能使用DataSource ds = new DruidDataSource()
因为DataSource接口中没有对应的setter方法来设置属性
``
如果把所有的第三方bean都配置到Spring的配置SpringConfig中,虽然可以,但是不利于代码阅读和分类管理,所有我们就想能不能按照类别将这些bean配置到不同的配置类中?
public class JdbcConfig
{ @Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds; }
}
方案1:使用包扫描引入
方案2: 使用@Import引入
注意:
扫描注解可以移除
@Import参数需要的是一个数组,可以引入多个配置类。
@Import注解在配置类中只能写一次,下面的方式是不允许的
@Configuration
//@ComponentScan("com.itheima.config")
@Import(JdbcConfig.class)
@Import(Xxx.class)
public class SpringConfig {
}
总结:
注解开发实现为第三方bean注入资源
在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?这些资源会有两大类,分别是简单数据类型 和引用数据类型。
现在的数据库连接四要素还是写在代码中,需要做的是将这些内容提
取到jdbc.properties配置文件
1.resources目录下添加jdbc.properties
2.配置文件中提供四个键值对分别是数据库的四要素
3.使用@PropertySource加载jdbc.properties配置文件
4.修改@Value注解属性的值,将其修改为${key},key就是键值对中的键的值
引用数据类型
步骤1:在SpringConfig中扫描BookDao
扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象
@Configuration
@ComponentScan("com.itheima.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
步骤2:在JdbcConfig类的方法上添加参数
@Bean
public DataSource dataSource(BookDao bookDao){
System.out.println(bookDao);
DruidDataSource ds=new DruidDataSource();
// ds.setDriverClassName("com.mysql.jdbc.Driver");
// ds.setUrl("jdbc:mysql://localhost:33066/spring_db");
// ds.setUsername("root");
// ds.setPassword("169527");
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象。
注解开发总结
Spring整合
1.Mybatis的执行流程
// 1. 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 2. 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
// 4. 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5. 执行SqlSession对象执行查询,获取结果User
AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
Account ac = accountDao.findById(2);
System.out.println(ac);
// 6. 释放资源
sqlSession.close();
说明:
第一行读取外部properties配置文件,Spring有提供具体的解决方案@PropertySource ,需要交给Spring
第二行起别名包扫描,为SqlSessionFactory服务的,需要交给Spring
第三行主要用于做连接池,Spring之前我们已经整合了Druid连接池,这块也需要交给Spring
前面三行一起都是为了创建SqlSession对象用的,那么用Spring管理SqlSession对象吗?
回忆下SqlSession是由SqlSessionFactory创建出来的,所以只需要将SqlSessionFactory交给Spring管理即可。
第四行是Mapper接口和映射文件(如果使用注解就没有该映射文件),这个是在获取到SqlSession以后执行具体 *** 作的时候用,所以它和SqlSessionFactory创建的时机都不在同一个时间,可能需要单独管理。
总结:Mybatis管什么呢?管的就是SqlSessionFactory对象!!!!!!
2.Spring整合Mybatis
第一步:导入整合需要的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
第二步:创建Spring的主配置类
@Configuration
@ComponentScan("com.itheima")
//@PropertySource:加载类路径jdbc.properties文件
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
public class SpringConfig {
}
第三步:创建数据源的配置类
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
第四步:主配置类中读properties并引入数据源配置类
第五步:创建Mybatis配置类并配置SqlSessionFactory
public class MybatisC {
//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("com.itheima.domain");
ssfb.setDataSource(dataSource);
return ssfb;
}
//定义bean,返回MapperScannerConfigurer对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
说明:
使用SqlSessionFactoryBean封装SqlSessionFactory需要的环境信息
SqlSessionFactoryBean是FactoryBean的一个子类,在该类中将SqlSessionFactory的创建进行了封装,简化对象的创建,只需要将其需要的内容设置即可。
方法中有一个参数为dataSource,当前Spring容器中已经创建了Druid数据源,类型刚好是DataSource类型,此时在初始化SqlSessionFactoryBean这个对象的时候,发现需要使用DataSource对象,而容器中刚好有这么一个对象,就自动加载了DruidDataSource对象。
使用MapperScannerConfigurer加载Dao接口,创建代理对象保存到IOC容器中
这个MapperScannerConfigurer对象也是MyBatis提供的专用于整合的jar包中的类,用来处理原始配置文件中的mappers相关配置,加载数据层的Mapper接口类。
MapperScannerConfigurer有一个核心属性basePackage就是用来设置所扫描的包路径
第六步:主配置类中引入Mybatis配置类
第七步:编写运行类
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService accountService = ctx.getBean(AccountService.class);
Account ac = accountService.findById(1);
System.out.println(ac);
}
支持Spring与Mybatis的整合就已经完成了,其中主要用到的两个类分别是:
SqlSessionFactoryBean
MapperScannerConfigurer
Spring整合Junit
Junit是一个搞单元测试用的工具,它不是我们程序的主体,也不会参加最终程序的运行,从作用上来说就和之前的东西不一样,它不是做功能的,看做是一个辅助工具就可以了
第1步:引入相关Jar包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
第2步::编写测试类
//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//设置Spring环境对应的配置类
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
//支持自动装配注入bean
@Autowired
private AccountService accountService;
@Test
public void testFindById(){
System.out.println(accountService.findById(1));
}
注意:
1.单元测试,如果测试的是注解配置类,则使用@ContextConfiguration(classes = 配置 类.class)单元测试,如果测试的是配置文件,则使@ContextConfiguration(locations={配置文件 名,…})
2.Junit运行后是基于Spring环境运行的,所以Spring提供了一个专用的类运行器,这个务必要设
置,这个类运行器就在Spring的测试专用包中提供的,导入的坐标就是这个东西
3.SpringJUnit4ClassRunner上面两个配置都是固定格式,当需要测试哪个bean时,使用自动装配加载对应的对象,下面的工作就和以前做Junit单元测试完全一样了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)