Spring Framework
1. 关于Spring
Spring框架主要解决了创建对象、管理对象的问题。
除了对象存在的时间(时长)以外,在实际项目开发中,还需要关注各个类型之间的依赖关系!
public class UserMapper { public void insert() { // 向数据表中的“用户表”中插入数据 } }
public class UserController { public UserMapper userMapper; public void reg() { userMapper.insert(); } }
在以上示例代码中,可视为“UserController
是依赖于UserMapper
的”,也可以把UserMapper
称之为“UserController
的依赖项”。
但是,在实际项目中,除了UserController
以外,还会有其它的组件也可能需要使用到UserMapper
,如果每个组件中都使用new UserMapper()
的语法来创建对象,就不能保证UserMapper
对象的唯一性,就违背了设计初衷。
为了更好的创建对象和管理对象,应该使用Spring框架!
2. 创建基于Spring的工程
当某个项目需要使用Spring框架时,推荐使用Maven工程。
创建名为spring01
的Maven工程,创建完成后,会自动打开pom.xml
文件,首先,应该在此文件中添加<dependencies>
节点,此节点是用于添加依赖项的:
<dependencies> </dependencies>
然后,Spring框架的依赖项的代码需要编写在以上节点的子级,而依赖项的代码推荐从 https://mvnrepository.com/ 网站查询得到,Spring的依赖项名称是spring-context
,则在此网站搜索该名称,以找到依赖项的代码,代码示例:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.14</version> </dependency>
3.通过Spring创建对象
package cn.tedu.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Random; @Configuration public class SpringBeanFactory { @Bean public Random random() { return new Random(); }}
public class SpringRunner { public static void main(String[] args) { // 1. 加载Spring AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringBeanFactory.class); // 2. 从Spring中获取对象 Random random = (Random) ac.getBean("random"); // 3. 测试使用对象,以便于观察是否获取到了有效的对象 System.out.println("random > " + random); System.out.println("random.nextInt() > " + random.nextInt()); // 4. 关闭 ac.close(); }}
-
在
AnnotationConfigApplicationContext
的构造方法中,应该将SpringBeanFactory.class
作为参数传入,否则就不会加载SpringBeanFactory
类中内容-
其实,在以上案例中,
SpringBeanFactory
类上的@Configuration
注解并不是必须的
-
-
在
getBean()
时,传入的字符串参数"random"
是SpringBeanFactory
类中的方法的名称 -
在
SpringBeanFactory
类中的方法必须添加@Bean
注解,其作用是使得Spring框架自动调用此方法,并管理此方法返回的结果 -
关于
getBean()
方法,此方法被重载了多次,典型的有:-
Object getBean(String beanName)
-
通过此方法,传入的
beanName
必须是有效的,否则将导致NoSuchBeanDefinitionException
-
-
T getBean(Class<T> beanClass)
;-
使用此方法时,传入的类型在Spring中必须有且仅有1个对象,如果没有匹配类型的对象,将导致
NoSuchBeanDefinitionException
,如果有2个,将导致NoUniqueBeanDefinitionException
-
-
T getBean(String beanName, Class<T> beanClass)
-
此方法仍是根据传入的
beanName
获取对象,并且根据传入的beanClass
进行类型转换
-
-
-
使用的
@Bean
注解可以传入String
类型的参数,如果传入,则此注解对应的方法的返回结果的beanName
就是@Bean
注解中传入的String
参数值
4.通过Spring创建对象--组件扫描
在pom.xml
中添加spring-context
的依赖项
参数("包名",...)
在AnnotationConfigApplicationContext
传入参数是一个basePackages
(根包),spring框架扫描这个包及子包,并尝试创建包中的组件对象(@Component
组件标记)
getBean
参数(类名(首字母小写))
1.参数("类名")
2.参数(类型)
3.参数("类名",类型)
组件注解
-
@Component 通用组件注解
-
@Controller 控制器类
-
@Service 业务类
-
@Repository 数据存取类
在上面4个注解中配置字符串参数,显式的指定Bean的名称
-
@Configuration 特殊组件,配置类
在配置类上加@ComponentScan指定扫描的包
5.2种Spring创建对象的区别
-
@Bean适用于所有场景(使用过程相对繁琐)
-
组件扫描只使用于自定义的类型,使用便捷
6.Spring管理对象的作用域
作用域默认是单例 从开始到结束,
单例情况下,默认不是懒加载
可以通过@lazy注解控制是否为懒加载模式
在类上添加@Scope("prototype")设置为多例模式
7.Spring管理对象的生命周期
由Spring创建并管理对象,开发人员没有对象的控制权,无法对此对象的历程进行干预
自定义只有初始化和销毁2个方法,在创建对象之后执行初始化方法,在销毁对象之前执行销毁方法.
关于这2个方法的声明:
-
访问权限: 推荐使用
public
-
返回值类型: 推荐使用
void
-
方法名称: 自定义
-
参数列表:推荐为空
在初始化方法的声明之前添加@PostConstruct
在销毁方法的声明之前添加@PreDestroy
此两个注解是来自java扩展包javax.annotation
仅当类的对象被spring管理且是单例,才讨论生命周期
通过@Bean方法管理的非自定义的类,可以在@Bean注解中配置initMethod
和destroyMethod
8.Spring的自动装配机制
@Autowired的装配机制
默认按类型装配
org.springframework.beans.factory.annotation
会根据需要装配的数据的类型在spring容器查找匹配的Bean(对象)的数量
-
0个,判断@Autowired的注解
required
属性值-
required=true,启动项目时报告异常
-
required=false,放弃自动装配,不会报告异常,使用时会出现NullPointerException
-
-
1个:直接装配
-
多个:自动尝试按照名称装配(属性的名称与Spring Bean的名称)
-
存在与属性名称匹配的Spring Bean:装配成功
-
不存在与属性名称匹配的Spring Bean:装配失败,启动项目时即报告异常
-
@Resource
默认按名称装配
来源(javax.annotation),先尝试个根据名字装配,失败再根据类型装配
如果某个方法是由Spring框架自动调
(通常是构造方法,或@Bean方法)
9.读取properties配置文件中的信息
在src/main/resources
文件夹下创建jdbc.properties
,
spring.jdbc.url=jdbc:mysql://localhost:3306/tedu spring.jdbc.driver=com.mysql.jdbc.Driver spring.jdbc.username=root spring.jdbc.password=1234 spring.jdbc.init-size=5 spring.jdbc.max-active=20
注意:自定义的属性名称建议添加一些前缀,避免与系统属性和Java属性冲突。
@Configuration @ComponentScan("cn.tedu.spring") @PropertySource("classpath:jdbc.properties") public class SpringConfig { }
@Component public class JdbcConfig { @Value("${spring.jdbc.url}") private String url; @Value("${spring.jdbc.driver}") private String driver; @Value("${spring.jdbc.username}") private String username; @Value("${spring.jdbc.password}") private String password; @Value("${spring.jdbc.init-size}") private int initSize; @Value("${spring.jdbc.max-active}") private int maxActive;
10.spring框架
-
了解spring的作用:创建对象,管理对象
-
掌握spring创建对象的两种方式:
-
在配置类(带
@Configuration
)中使用@bean
方法 -
组件扫描,在类上添加组件注解
-
@Component @Controller @Service @Repository
-
-
自定义的类,使用组件扫描+组件注解的方式,不是自定义的类必须在配置类中添加
@Bean
方法
-
-
了解Spring Bean的作用域和生命周期
-
掌握@AutoWired自动装配,理解装配机制
-
@AutoWired和@Resource的区别
-
-
掌握读取.properties配置文件中的数据
-
使用@PropertySource注解指定需要读取的文件
-
读取配置
-
使用@Value注解将值注入属性(推荐使用)
-
自动装配environment对象,调用getProperty方法获取配置值
-
-
-
了解Spring的IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入
-
Spring框架基于DI实现IoC,DI是一只实现手段,IoC是最终实现的目标/效果
-