概述
我们可以将一些bean组件交给Spring来管理,并且Spring还支持单实例bean和多实例bean。
我们自己写的类,自然可以通过@ComponentScan + 标注组件注解(@Controller、@Service、@Repository、@Componet)的形式将其注册到IOC容器中,但这种方式比较有局限性,局限于我们自己写的类,自己写的类可以把这些注解标注到类上。
如果我们不是我们自己写的类,比如说我们在项目中会经常引入一些第三方的类库,我们需要将这些第三方类库中的类注册到Spring容器中,该怎么办呢?此时,我们可以使用@Bean或者@Import注解将这些类快速的导入Spring容器中。
接下来,我们来一起探讨如何使用@Import注解给容器中快速导入一个组件。
注册bean的方式
向Spring容器中注册bean通常有以下几种方式:
- 包扫描+给组件标注注解(@Controller、@Service、@Repository、@Component),但这种方法比较有局限性,局限于我们自己写的类。
- @Bean注解,通常用于导入第三方包中的组件。
- @Import注解,快速向Spring容器中导入一个组件。
@Import注解概述
Spring3.0之前,创建bean可以通过XML配置文件与扫描特定包下面的类来将类注入到Spring IOC容器内。而在Spring3.0之后提供了JavaConfig的方式,也就是将IOC容器里面bean的元信息以Java代码的方式进行描述,然后我们可以通过@Configuration与@Bean这两个注解配合使用来将原来配置在XML文件里面的bean通过Java代码的方式进行描述。
@Import注解提供了@Bean注解的功能,同时还有XML配置文件里面标签组织多个分散的XML文件的功能,当然在这里是组织多个分散的@Configuration,因为一个配置类约等于一个XML配置文件。
@Import注解的源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
从源码里面可以看出@Import可以配合Configuration、ImportSelector以及ImportBeanDefinitionRegistrar来使用,也可以把@Import当成@Bean来使用(不过只能标准在类上)。
注意:@Import注解只允许放到类上面,不允许放到方法上。
@Import注解的使用方式
@Import注解的三种用法主要包括:
- 直接填写class数组的方式。
- ImportSelector接口的方式,即批量导入。
- ImportBeanDefinitionRegistrar接口方式,即手工注册bean到容器中。
我们先来看第一种方法,即直接填写class数组的方式,其他两种方式后面讲解。
@Import导入组件的简单示例
没有使用@Import注解时的效果
首先,我们创建一个Color类,这个类是一个空类,没有成员变量和方法,如下所示。
package com.meimeixia.bean;
public class Color {
}
然后,我们在IOCTest类中创建一个testImport()方法,在其中输出Spring容器中所有bean定义的名字,来查看是否存在Color类对应的bean实例,以此来判断Spring容器中是否注册有Color类对应的bean实例。
@Test
public void testImport() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
}
运行以上testImport()方法之后,输出的结果信息如下所示。
可以看到Spring容器中并没有Color类对应的bean实例。
使用@Import注解时的效果
首先,我们在MainConfig2配置类上添加一个@Import注解,并将Color类填写到该注解中,如下所示。
package com.meimeixia.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import com.meimeixia.bean.Color;
import com.meimeixia.bean.Person;
import com.meimeixia.condition.LinuxCondition;
import com.meimeixia.condition.WindowsCondition;
// 对配置类中的组件进行统一设置
@Conditional({WindowsCondition.class}) // 满足当前条件,这个类中配置的所有bean注册才能生效
@Configuration
@Import(Color.class) // @Import快速地导入组件,id默认是组件的全类名
public class MainConfig2 {
@Lazy
@Bean("person")
public Person person() {
System.out.println("给容器中添加咱们这个Person对象...");
return new Person("美美侠", 25);
}
@Bean("bill")
public Person person01() {
return new Person("Bill Gates", 62);
}
@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person02() {
return new Person("linus", 48);
}
}
然后,我们运行IOCTest类中的testImport()方法,会发现输出的结果信息如下所示。
可以看到,输出结果中打印了com.meimeixia.bean.Color,说明使用@Import注解快速地导入组件时,容器中就会自动注册这个组件,并且id默认是组件的全类名。
@Import注解还支持同时导入多个类,例如,我们再次创建一个Red类,如下所示。
package com.meimeixia.bean;
public class Red {
}
然后,我们也将以上Red类添加到@Import注解中,如下所示。
package com.meimeixia.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import com.meimeixia.bean.Color;
import com.meimeixia.bean.Person;
import com.meimeixia.condition.LinuxCondition;
import com.meimeixia.condition.WindowsCondition;
// 对配置类中的组件进行统一设置
@Conditional({WindowsCondition.class}) // 满足当前条件,这个类中配置的所有bean注册才能生效
@Configuration
@Import({Color.class, Red.class}) // @Import快速地导入组件,id默认是组件的全类名
public class MainConfig2 {
@Lazy
@Bean("person")
public Person person() {
System.out.println("给容器中添加咱们这个Person对象...");
return new Person("美美侠", 25);
}
@Bean("bill")
public Person person01() {
return new Person("Bill Gates", 62);
}
@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person02() {
return new Person("linus", 48);
}
}
接着,我们运行IOCTest类中的testImport()方法,发现输出的结果信息如下所示。
可以看到,结果信息中同时输出了com.meimeixia.bean.Color和com.meimeixia.bean.Red,说明Color类对应的bean实例和Red类对应的bean实例都导入到Spring容器中去了。
参考
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100000.html