第一部分:Spring
背景:
BookDao
package com.itheima.dao;
public interface BookDao {
public void save();
}
BookDaoImpl
package com.itheima.dao.impl;
import com.itheima.dao.BookDao;
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
App.java
package com.itheima;
import com.itheima.dao.BookDao;
import com.itheima.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
}
}
一、配置Bean
第一种方式:在applicationContext.xml中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<!--2.配置bean-->
<!--bean标签标示配置bean
id属性标示给bean起名字
class属性表示给bean定义类型-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
其中:
spring配置文件applicationContext.xml,并在配置文件中完成bean的配置;
<bean></bean>
代表配置一个bean;
class="com.itheima.dao.impl.BookDaoImpl"
:配置的bean设定它的类型;
id
属性:给bean起名字;
不需要设置扫描
运行App.java
输出:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
通过spring的配置文件applicationContext.xml创建容器,并获得容器对象。容器内部使用构造方法, 静态工厂和实例工厂来实例化bean对象。
第二种方式:注解开发定义bean
步骤1:删除原XML配置
将配置文件中的 标签删除掉
<bean id="bookDao" class="com.itheima.dao.1 impl.BookDaoImpl"/>
步骤2:Dao上添加注解
在BookDaoImpl类上添加@Component 注解
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
@Component:定义bean,注解不可以添加在接口上,因为接口是无法创建对象的;
@Component(“bookDao”):定义bean且起名字;
@Controller:@Component衍生注解,用于表现层bean定义;
@Service:@Component衍生注解,用于业务层bean定义;
@Repository:@Component衍生注解,用于数据层bean定义;
原来的xml中的class:在哪个类上加就代表这个class是谁
注意:
@Component注解不可以添加在接口上,因为接口是无法创建对象的
在BookDaoImpl中加注解可替代 作用,名字可有可无,没有设置value会有一个默认值就是当前类名首字母小写,所以也可以按照名称,也可以就按类型获取。
XML与注解配置的对应关系:
步骤3:配置Spring的注解包扫描
为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<context:component-scan base-package="com.itheima"/>
</beans>
说明:
component-scan
- component:组件,Spring将管理的bean视作自己的一个组件
- scan:扫描base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
- 包路径越多[如:com.itheima.dao.impl],扫描的范围越小速度越快
- 包路径越少[如:com.itheima],扫描的范围越大速度越慢
- 一般扫描到项目的组织名称即Maven的groupId下[如:com.itheima]即可。
步骤4:运行程序
运行App.java
第三种方式:纯注解开发模式
实现思路为:
将配置文件applicationContext.xml删除掉,使用类来替换。
步骤1:创建配置类
创建一个配置类SpringConfig
public class SpringConfig {
}
步骤2:标识该类为配置类
在配置类上添加@Configuration 注解,将其标识为一个配置类,替换applicationContext.xml
@Configuration
public class SpringConfig {
}
步骤3:用注解替换包扫描配置
在配置类上添加包扫描注解@ComponentScan 替换<context:component-scan base-package=“”/>
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
步骤4:创建运行类并执行
创建一个新的运行类AppForAnnotation
public class AppForAnnotation {
public static void main(String[] args) {
ApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
运行AppForAnnotation,可以看到两个对象依然被获取成功
至此,纯注解开发的方式就已经完成了,主要内容包括:
- Java类替换Spring核心配置文件
- @Configuration注解用于设定当前类为配置类
- @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({com.itheima.service","1 com.itheima.dao"})
- 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器
ApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);
在SpringBoot中只需要加@Configuration,不需要设置扫描,因为springboot默认会设置扫描的包,加载为了bean;
当我们配置其他例如druid时需要扫描到它所以一定要加上@Configuration
注解。
第二部分:SpringBoot
Springboot0101QuickstartApplication.java文件中包含以下代码
package com.itheima;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Springboot0101QuickstartApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot0101QuickstartApplication.class, args);
}
}
SpringApplication.run(Springboot0101QuickstartApplication.class, args);
功能就是一个容器
那么获得容器之前需要配置bean并扫描,那么springboot是如何工作的呢?
我们发现springboot有@SpringBootApplication
具体来讲@SpringBootApplication
注解里面包含
@SpringBootConfiguration
包含@Configuration
所以@SpringBootApplication
包含@Configuration
和@ComponentScan
,和第一部分第三种方式:纯注解开发一样。在配置类中只需要加上@Configuration
并不需要设置@ComponentScan({“com.itheima.service”,“com.itheima.dao”}),这是因为SpringBoot本身在主启动类中就使用@ComponentScan
设置了扫描的包,@ComponentScan
默认会扫描当前所在包及其子包,会将@Configuration
和@Component及其泛化注解配置的bean加载到Spring容器。
SpringBoot的引导类是Boot工程的执行入口,运行main方法就可以启动项目。
SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean。
第三部分:SpringBoot使用Mybatis
使用Mybatis可以使用xml和注解开发的形式,但是随着sql的复杂注解开发有时候并不能满足要求。
无论使用xml和注解开发都需要在配置中进行扫描。
那么spring怎么知道这个类需要做自动代理呢,原来我们是通过扫描的方法设置扫描的包。是在mybatis-config.xml
原理是需要知道被代理的类。现在在SpringBoot中不需要配置mybatis-config.xml,SpringBoot设置了默认的UserMapper.xml的路径,UserMapper.xml放在指定目录src\main\resources\mapper\UserMapper.xml
中将会被自动扫描。
- 上面的是通过UserMapper.xml知道这个类需要做自动代理。
- UserMapper上不加@Mapper,启动类上添加
@MapperScan("com.atguigu")
,就可以将指定包下的所有的mapper接口所动态生成的代理类交给IOC容器管理。需要注意的是idea提示注入问题,实际上可以正常运行,要是不想idea提示可以在UserMapper上加上@Repository注解。 - 在UserMapper接口上加上
@Mapper
表示被容器识别到,创建这个的代理类,这样就自动将代理类交给IOC容器管理。另外有了@Mapper
就不需要@MapperScan("com.atguigu")
,两者作用一样,@Mapper
这并不是配置bean的含义,切勿混淆。MyBatis中的Mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。
容易混淆的是:我们一般需要配置为bean,然后扫描才能使用它。这里我们只进行了扫描而没有去配置bean。我们这里使用的是自动代理,扫描也是扫描哪一个需要创建代理类,并不是扫描bean,故不需要配置bean。
说明:springboot设置了自动扫描的包,会扫描到@Mapper
的类,创建这个的代理类,这样就自动将代理类交给IOC容器管理。
如果不加@Mapper
就需要在启动类上添加@MapperScan("com.atguigu")
就可以将指定包下的所有的mapper接口所动态生成的代理类交给IOC容器管理。
@Repository那是基于代码的开发,简单来说就是手写 JDBC,在dao的impl中使用注入bean的方式,使用@Repository配置了bean在spring中需要设置扫描,在springboot中不需要额外设置扫描。