在spring中Bean是我们必须知道的一个内容。但是很多时候我们只是知道Bean但是我们并不了解到底什么是Bean。接下来让我们近距离接触Bean。
一,java对象可以被称之为Bean吗?
大多数下我们会认为java对象其实就是一个Bean,这种说法是错误的。我们一般称呼是Bean的java对象为javaBean,只有注册到spring容器中的java对象才能称呼为javaBean。
二,由上面的问题引出什么是容器呢
容器就是我们在javaweb阶段一直接触的ServletContext,和在spring阶段初期接触的基于xml文件开发方式的ClassPathXmlApplicationContext容器,和基于java配置类开AnnotationConfigApplicationContext容器。他们都是容器。不同种开发方式会把不同的Bean放到不同类型的容器中。之后我们可以通过容器继承到的getBean()方法取得我们需要的Bean。这里不拓展。
总结容器的作用是用来存放Bean和获取Bean的提供与我们开发者方便使用。
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext();
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(WebConfig.class);
三,java对象和javaBean有什么区别呢
java对象就是我们正常情况下利用反射和new关键字创建出来的。javaBean比java对象多了一些信息比如定义javaBean的作用域是不是单例的还是其他另外几种,是否是懒加载的。这里引出一个底层类BeanDefinition他是对在java对象转化为javaBean的时候对Java对象进行转化赋值之后注册到容器中的。只有被注册到spring容器中的java对象才能称呼为Bean,这时候的java对象也称之为javaBean
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
//省略
}
我们在xml中会定义javaBean的一些属性
<bean id="mybean1" class="com.example.spring01.Beanfactory.ApplicationContexts.Bean1" scope="prototype" lazy-init="true"/>
scope="prototype" lazy-init="true"就是普通java对象没有的BeanDefinition属性,也就是说javaBean比普通的java对象多出了BeanDefinition的属性。
四,要如何把带有BeanDefinition属性的java对象,和普通java对象注册到容器中呢注册到
xml开发方式中其实我们只需要把xml文件填写进入ClassPathXmlApplicationContext中就可以
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
可是为社么这样子就可以呢,深入一下底层看一下是如何xml中定义的bean标签是如何注册到容器中的。
<bean></bean>标签-->BeanDefinition对象-->注册到工厂中(也可以说注册到容器中)-->成为javaBean
<bean>标签
<bean id="mybean1" class="com.example.spring01.Beanfactory.ApplicationContexts.Bean1" scope="prototype" lazy-init="true"/>
在spring底层会通过以下2步把xml中的<bean>标签注册成BeanDefinition对象
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(new GenericApplicationContext());
//把资源路径告诉XmlBeanDefinitionReader进行BeanDefinition对象的创建
reader.loadBeanDefinitions("bean.xml");
把BeanDefinition对象注册到工厂中
//获得工厂
DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
//这里传入工厂的实例对象就会自动把BeanDefinition对象注册到工厂中
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("bean.xml");
这样Bean就注册完成了。
完整代码
public class ApplicationContexts {
public static void main(String[] args) {
//获得bean工厂
DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println("注入前");
System.out.println(beanDefinitionName);
}
//使用XmlBeanDefinitionReader把xml里面的bean给difinition出来然后塞到beanFactory中
XmlBeanDefinitionReader xmlBeanDefinitionReader=new XmlBeanDefinitionReader(beanFactory);
//告诉这个XmlBeanDefinitionReader他应该去哪里得到这个xml,这里只能加载一些bean的定义信息
xmlBeanDefinitionReader.loadBeanDefinitions("bean.xml");
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println("注入后");
System.out.println(beanDefinitionName);
}
}
普通的Bean注册就简单多了但是在注册过程中spring会默认给他配上BeanDefinition的一些属性,也可以自己定义。
@Test
void TestBlog(){
DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
//获取BeanDefinition对象
AbstractBeanDefinition scope = BeanDefinitionBuilder.genericBeanDefinition(F1.class).setScope("scope").getBeanDefinition();
//注册
beanFactory.registerBeanDefinition("f1",scope);
}
还有注解方式的注册过程,内容太多可能以后会讲。
请大家多多指教。