系列文章目录
文章目录
一、Spring Framework
1.1 IoC(Inversion of Control)
- 控制反转的含义:之前的代码new对象的控制权在程序员手中,现在将new对象的控制权交给外部,而这个外部就是由Spring提供的IoC容器,所有对象的创建都在IoC容器中进行。
1.2 DI(Dependency Injection)
-
service运行需要依赖dao对象,如果说IoC容器只是单独给一个service对象而不给dao对象,会出现空指针异常。所以此时IoC容器帮我们将有关系的Bean绑定好了创建。
-
依赖注入的含义:在IoC容器中Bean与Bean之间建立依赖关系的整个过程
1.3 IoC代码案例
- 添加案例中需要的类和接口
- 在resource下添加Spring配置文件并配置bean相关信息
注意事项:bean定义时id属性在同一个上下文中(配置文件)不能重复
<?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">
<!-- bean标签表示配置bean-->
<!-- id属性是给bean起名字-->
<!-- class属性代表bean的定义类型-->
<bean id="bookDao" class="com.rose.dao.BookDaoImpl"/>
<bean id="bookService" class="com.rose.service.BookServiceImpl"/>
</beans>
- 使用Spring提供的接口创建IoC容器才能拿到bean对象
ApplicationContect是一个接口不能实例化
public class App {
public static void main(String[] args) {
//获取 IoC容器
ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
//获取 bean
BookService bookService=(BookService) context.getBean("bookService");
bookService.save();
}
}
1.4 DI代码案例
- Service中还存在new的形式创建对象,此时需要完全将创建对象的能力交给Spring,先删除Service中new的方式
- 提供一个setter方法将Dao对象传入Service
在BookServiceImpl类中,为BookDao提供setter方法
public class BookServiceImpl implements BookService{
//删除业务层使用new方式创建dao对象
private BookDao bookDao;
@Override
public void save() {
System.out.println("book service save...");
bookDao.save();
}
//提供对应set方法注入dao对象
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
- 在配置文件中,配置Bean之间的依赖关系
<?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">
<!-- bean标签表示配置bean-->
<!-- id属性是给bean起名字-->
<!-- class代表bean的定义类型-->
<bean id="bookDao" class="com.rose.dao.BookDaoImpl"/>
<bean id="bookService" class="com.rose.service.BookServiceImpl">
<!-- 配置service和dao的关系-->
<!-- name属性表示配置那一个具体属性-->
<!-- ref表示参考哪一个bean-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
虽然id和ref都是bookDao,name指的是属性名称,ref是需要依赖注入的bean
1.5 Bean的实例化方法
默认情况下,Spring创建的bean对象都是单例的
- 构造方法
public class BookDaoImpl implements BookDao{
public BookDaoImpl(){
System.out.println("book dao constructor is running...");
}
@Override
public void save() {
System.out.println("book dao save... ");
}
}
- 静态工厂
public interface OrderDao {
void save();
}
public class OrderDaoImpl implements OrderDao{
@Override
public void save() {
System.out.println("order dao save ...");
}
}
//配置信息
<!-- 使用工厂方法实例化Bean-->
<bean id="orderDao" class="com.rose.factory.OrderDaoFactory" factory-method="getOrderDao">
</bean>
- 实例工厂
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
在spring的配置文件中添加以下内容
<bean id="userFactory" class="com.rose.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
- FactoryBean的拓展方法(重点)
1.6 setter注入
- 注入引用类型
- 注入基本类型
public class BookDaoImpl implements BookDao{
private int connectionNum;
private String baseName;
public void setBaseName(String baseName) {
this.baseName = baseName;
}
public void setConnectionNum(int connectionNum) {
this.connectionNum = connectionNum;
}
@Override
public void save() {
System.out.println("book dao save... "+connectionNum+baseNum);
}
}
//配置信息
<bean id="bookDao" class="com.rose.dao.BookDaoImpl">
<property name="connectionNum" value="10"/>
<property name="baseName" value="mysql"/>
</bean>
1.7 构造器注入
public class BookServiceImpl implements BookService{
private BookDao bookDao;
private UserDao userDao;
public BookServiceImpl(BookDao bookDao, UserDao userDao) {
this.bookDao = bookDao;
this.userDao = userDao;
}
@Override
public void save() {
System.out.println("book service save...");
bookDao.save();
userDao.save();
}
//配置信息
<bean id="bookDao" class="com.rose.dao.BookDaoImpl"/>
<bean id="userDao" class="com.rose.dao.UserDaoImpl"/>
<bean id="bookService" class="com.rose.service.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
</bean>
- 两种简化配置参数的方法
1.8 小结
二、注解开发
2.1 注解定义Bean
- 添加配置文件信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="需要扫描的包的路径"/>
</beans>
- 为实现的类添加注解
@Component注解不可以添加在接口上,因为接口是无法创建对象的。
- 配置文件与注解对应关系
- Component注解的衍生注解
2.2 纯注解开发(Spring 3.0)
- 创建一个配置类,并标识该类为配置类,注解替换application.xml
@Configuration //配置类
@ComponentScan("com.rose.dao")//包扫描配置信息
public class SpringConfig {
}
- 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
2.3 bean的生命周期管理
- @Scope注解 配置bean为单例或者为非单例模式,默认为单例
- bean的生命周期管理,在初始化方法上添加@PostConstruct和在销毁方法上@PreDestroy注解
- 要想看到两个方法执行,需要注意的是destroy()方法只有在容器关闭的时候才会执行,所以需要修改App的类为Annotation类
2.4 依赖注入(重点)
Spring为了使用注解简化开发,并没有提供构造函数注入、setter注入对应的注解,只提供了自动装配的注解实现
- @Autowired 自动装配(注定引用类型注入)
@Autowired可以写在属性上,也可也写在setter方法上,最简单的处理方式是写在属性上并将setter方法省略
- 自动装配原理
自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值,普通反射只能获取public修饰的内容,暴力反射除了获取public修饰的内容还可以获取private修改的内容,所以此处无需提供setter方法
- @Autowired是按照类型装配,如果一个接口有多个实现类(相同类型的bean)就需要配合@Qualifier注解实现按照名称注入
- 使用@Value简单类型注入
- 注解读取properties配置文件文件信息
2.5 注解开发管理第三方bean(重点)
- 使用独立的配置类管理第三方Bean
@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象,第三方配置类不用加@Configuration注解
@Configuration //核心配置类
@Import(JdbcConfig.class)//导入外部配置类
@ComponentScan({
"com.rose.dao","com.rose.service"})
public class SpringConfig {
}
public class JdbcConfig {
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://127.0.0.1:3306/spring_db")
private String url;
@Value("root")
private String username;
@Value("root")
private String password;