Spring中核心的功能就是IoC和AOP,本文主要主要讲解IOC中实例注册和使用的方法。
Spring Boot常见注解
Spring IoC容器可以容纳我们所开发的各种Bean,并且可以从中获取各种注册在Spring IoC容器里的Bean。
Spring IoC容器的设计主要是基于BeanFactory和ApplicationContext两个接口,其中ApplicationContext是BeanFactory的子接口之一。换句话说BeanFactory是Spring IoC容器所定义的最底层接口,而ApplicationContext是其高级接口之一,并且对BeanFactory功能做了许多有用的扩展,所以在绝大部分的工作场景下,都会使用ApplicationContext作为Spring IoC容器。
1、BeanFactory
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。
在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("配置文件"));
2、ApplicationContext
Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文。 Application Context 是 spring 中较高级的容器。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。ApplicationContext 包含 BeanFactory 所有的功能。一般情况下,相对于 BeanFactory,ApplicationContext 会更加优秀。
ApplicationContext的3个常用实现类:
●ClassPathXmlApplicationContext:从 类路径下加载XML配置文件
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
●FileSystemXmlApplicationContext: 从文件系统中加载XML配置文件
ApplicationContext context=new FileSystemXmlApplicationContext("D:/applicationContext.xml");
●XmlWebApplicationContext:从Web系统中加载XML配置文件
bean容器的启动
bean在实例化之前,必须是在bean容器启动之后。所以就有了两个阶段:
(1)bean容器的启动阶段;
①首先是读取bean的xml配置文件或配置类,然后解析xml文件或配置类中的各种bean的定义,将xml文件或配置类中的每一个bean元素分别转换成一个BeanDefinition对象,其中保存了从配置文件中读取到的该bean的各种信息。
②然后通过BeanDefinitionRegistry将这些BeanDefinition对象注册到beanFactory中。
(2)容器中bean的实例化阶段;
实例化阶段主要是通过反射或者CGLIB对bean进行实例化。
1、xml文件配置方式
(1)Book类
public class Book {
private String name;
private String author;
private double price;
public Book() {
}
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", publicationDate=" + publicationDate +
'}';
}
}
(2)beans.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">
<bean id="book" class="newstar.springboot.entity.Book4">
<property name="name" value="西游记"/>
<property name="author" value="吴承恩"/>
<property name="price" value="30"/>
</bean>
</beans>
(3)获取Bean实例
public class MainTest {
public static void main(String []args){
//IOC容器加载配置文件,将类注册入容器中
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//从IOC容器中获取Bean实例
Book book= (Book) context.getBean("book");
System.out.println(book);
}
}
(2)配置类方式
(1)Book类同上
(2)配置类
@Configuration //配置类==配置文件
public class MainConfig {
//@Conditional({Conditional}) :按照一定的条件进行判断,满足条件给容器中注册bean
//@Scope("prototype"):调整作用域,默认是单实例singleton
//@Lazy:懒加载模式,指定在容器启动时不会创建bean实例,而是获取对象时再创建bean实例
@Bean //将该类注册进入IOC容器
public Book book(){
return new Book("罗贯中","三国演义",20);
}
}
(3)获取Bean实例
public class MainTest {
public static void main(String []args){
//IoC容器加载配置类,将配置类注册入容器中
ApplicationContext app=new AnnotationConfigApplicationContext(MainConfig.class);
//从IoC容器中获取Bean
Book book= (Book) app.getBean("book");
System.out.println(book);
}
}
(3)配置类+配置文件方式——@ImportResource注解
@ImportResource注解用于导入Spring的配置文件,让配置文件里面的内容生效
(就是以前写的springmvc.xml、applicationContext.xml或者自定义的xxx.xml)。
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,不能自动识别;如果想让Spring的配置文件生效加载进来,就必须使用@ImportResource注解。
1、包扫描 + 组件标注注解
(1)包扫描@ComponentScan
@ComponentScan(value = "com.tan", excludeFilters = {
//type:按什么类型排除,以上是按注解去排除
//classes:指定扫描的时候按照什么规则排除哪些组件
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
})
参数说明:
● value:指定要扫描的包
● 包过滤扫描:
excludeFilters = Filter[]:指定扫描的时候按照什么规则排除哪些组件
includeFilters = Filter[]:指定扫描的时候只需要包含哪些组件,(需要关闭默认全部扫描的设置,useDefaultFilters=false)
(2) 组件标注注解
@Controller、@Service、@Repository、@Component
2、@Import导入组件
(1)@Import(要导入到容器中的组件):容器中就会自动注册这个组件,id默认是全类名。
(2)@ImportSelector: 返回需要导入的组件的全类名数组。
(3)@ImportBeanDefinitionRegistrar:手动将bean自定义注册到容器中。
3、spring提供的FactoryBean(工厂bean)
AnnotationConfigApplicationContext
(1)Book类
public class Book {
@Value("红楼梦")
private String name;
@Value("曹雪芹")
private String author;
@Value("25")
private double price;
}
(2)注册实例化
public class Test {
public static void main(String []args){
//IoC容器加载Book类并注册实例化
ApplicationContext app=new AnnotationConfigApplicationContext(Book.class);
//从IoC容器中获取Bean
Book book= (Book) app.getBean("book");
System.out.println(book);
}
}
1、配置文件方式
ClassPathXmlApplicationContext类
public class MainTest {
public static void main(String []args){
//IOC容器加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//从IOC容器中获取Bean实例
Book book = (Book) context.getBean("book");
System.out.println(book);
}
}
2、注解方式
AnnotationConfigApplicationContext类
public class MainTest {
public static void main(String []args){
//IoC容器加载配置类
ApplicationContext app=new AnnotationConfigApplicationContext(MainConfig.class);
//从IoC容器中获取Bean
Book book= (Book) app.getBean("book");
System.out.println(book);
}
}
3、SpringApplication
SpringApplication是springboot驱动spring应用上下文的引导类,他的run()方法启动Spring应用,实质上是为Spring应用创建并初始化Spring上下文。
SpringApplication.run()的底层其实就是new了一个SpringApplication的对象,并执行run()方法
ApplicationContext是Spring框架中一个很重要的接口,它扩展了BeanFactory,增加了很多常用的功能。SpringBoot启动过程中,SpringApplication通常会选择合适的ApplicationContext实现类,在默认情况下,如果是Web应用,则会创建AnnotationConfigEmbeddedWebApplicationContext类的对象;否则会创建AnnotationConfigApplicationContext类的对象。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Application.class,args);
String[]names = run.getBeanDefinitionNames();
for(String name:names){
System.out.println(name);
}
}
}
在使用@Autowired注解进行Bean装配时,一定不能使用new进行创建对象
!(否则报错空指针)当通过new的方式创建一个对象的时候,虽然期望使用了注解@Autowired对这个对象进行装配,但是Spring是不会这么做的,因为Spring不会对任意一个new 出来的对象进行自动装配,只有这个对象也是一个在Spring中注册过的Bean,才会获得自动装配的功能。
在使用Spring进行自动注入的过程中,只会对通过读取Spring的配置文件或者配置类后产生的实例进行自动注入。
手动new出来的实例是无法获得在Spring中注册过得实例,这是 因为手动new 的实例并不是Spring 在初始化过程中注册的实例
。