开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情
一、xml 配置文件
这种方式在 SpringMVC 中是常用的方式,Spring 启动时会读取配置文件,并将配置文件中配置好的类加入到 IOC 容器中。
<!--spring.xml-->
<beans>
<bean id="user" class="com.shacoz.bean.User" />
</beans>
这里我们测试使用main函数。
使用ClassPathXmlApplicationContext()读取配置并启动一个 Spring IOC 容器。调用容器的getBean方法返回需要的对象。
public class Main {
public void getBeanOne() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
}
二、配置类
这种方式比较类似于第一种配置文件,但是这种更效率。
创建一个配置类,配合使用@Bean注解,以成员方法的形式返回 Bean 实例。
//在配置类中返回new出来的Bean,效率比第一种高
public class ConfigBean {
@Bean
public User user(){
return new User();
}
}
使用AnnotationConfigApplicationContext()读取配置类并启动一个 Spring IOC 容器。调用容器的getBean()方法返回需要的对象。
public class Main {
public void getBeanTwo() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigBean.class);
User user = context.getBean("user", User.class);
System.out.println(user);
}
}
三、扫描包
通过@ComponentSacn扫描包形式获取 Bean,被扫描的包下的所有带@Component注解的类都会被认为是 Bean。
@ComponentScan("com.shacoz.bean")
public class ConfigBean {
}
四、BeanDefinition 构建
编程式使用 BeanDefinition 构建 Bean,前三种方式也是基于底层 BeanDefinition 构建出来的。
这种方式更复杂,也更底层。
public class Main{
public void main(){
// 创建Spring容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 创建一个BeanDefinition,用来描述Bean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(Dog.class);
// 将bean放入Spring容器中
applicationContext.registerBeanDefinition("dog",beanDefinition);
// 刷新Spring容器
applicationContext.refresh();
// 获取Bean
Dog dog = applicationContext.getBean("dog", Dog.class);
System.out.println(dog);
}
}
五、FactoryBean 构建
使用 FactoryBean 构建特殊 Bean,使用 FactoryBean,Spring 会构建两个 Bean,一个是外层类的类型,一个是返回 Bean 的类型,外层类型是通过 Bean 名字前面加&符号获取。
// 创建一个Cat对象,外层是Animal
public class Animal implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new Cat(); // 返回Cat对象
}
@Override
public Class<?> getObjectType() {
return Cat.class;
}
}
创建容器后,外层类型作为 Bean 的类型注册到容器中,在调用getBean()方法时,默认返回getObject()返回的对象。 如果在 Bean 的名字前面加&,则可以获取到外层类型。
public class Main{
public void getBeanFive(){
// 创建Spring容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 创建一个BeanDefinition,用来描述Bean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
// 构建两个Bean,一个是Animal类型的,一个Cat类型的
beanDefinition.setBeanClass(Animal.class);
// 将bean放入Spring容器中
applicationContext.registerBeanDefinition("cat",beanDefinition);
// 刷新Spring容器
applicationContext.refresh();
// 获取Bean,通过cat获取的是Cat类型的,&cat则获取Animal类型的
Cat cat = applicationContext.getBean("cat", Cat.class);
Animal cat = applicationContext.getBean("&cat", Animal.class);
System.out.println(cat);
}
}
FactoryBean 产生单个 Bean,在 IOC 容器的基础上给 Bean 的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂 Bean,由 Spring 管理后,生产的对象是由getObject()方法决定的。
// FactoryBean 源码
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
六、registerBean 直接注册 Bean
在构建 Bean 时使用 Supplier 初始化 Bean 的参数,当然也可以做一些逻辑操作。Supplier 可以简写到 lambda 表达式。
public class Main{
public void getBeanSix(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 构建Supplier可以在构建Bean时初始化Bean的相关参数
applicationContext.registerBean(Cat.class, new Supplier<Cat>() {
@Override
public Cat get() {
Cat cat = new Cat();
cat.setName("咪咪");
return cat;
}
});
// 使用Lambda表达式简写Supplier
applicationContext.registerBean(Dog.class, () -> {
Dog dog = new Dog();
dog.setName("汪汪");
return dog;
});
applicationContext.refresh();
Cat cat = applicationContext.getBean("cat", Cat.class);
Dog dog = applicationContext.getBean("dog", Dog.class);
System.out.println(cat);
System.out.println(dog);
}
}
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情