概览:
1.通过
然后在代码中得到这个bean来使用:
通过ClassPathXmlApplicationContext类加载spring.xml文件,得到一个对象
然后通过对象的get方法去获取bean
2.通过@bean注解来定义bean
注意这里返回User对象,本身就要先定义一个User类
通过 AnnotationConfigApplicationContext这个注解类来加载我们定义bean的这个类config.class
然后通过这个对象的get方法去获得bean
3.@component注解定义bean
使用@component 注解来定义bean,在xml中可以通过这个标签来扫描包,包里面有@ component注解的都会被扫描为bean
也可以直接通过@componentScan注解来扫描:
如下扫描com.luban这个包,直接把这里的定义bean的代码注释掉,直接在User类的上方通过@component注解来定义bean,扫描com.luban的时候就发现到了User类下面的@component注解,就会把User类定义为spring的bean
注释掉这个:
在User类上面添加@component注解
4.@service @controller等 用这些实际上也是用的@component注解,因为在@service @controller注解里面实际就写了@component注解
点进去@service看看源码:
如下@service注解源码里面就用了@component注解
5.通过beanDefintion编程式定义
注:有编程式和声明式,beanDefintion属于编程式,上面的注解和xml都属于声明式
声明式底层也是依赖beanDefintion
6.FactoryBean (比较特殊)
新建一个Person类
新建一个类继承FactoryBean接口,实现两个方法,第一个方法返回Person对象,第二个方法返回Person对象的类型
然后还是通过编程式来定义这个bean试一下:
通过applicationContext.registerBeanDefinition方法把bean注入到spring容器中,名字是user,然后通过这个user来获取bean赋值给ZhouyuFactoryBean时报错,说类型不匹配。
这是什么原因呢?
这是FactoryBean 特殊情况,FactoryBean 会定义两个bean,一个是本身的这个ZhouyuFactoryBean,还有一个就是,ZhouyuFactoryBean里面返回的这个对象Person的bean
获取bean时通过user获取到的bean是person,通过&user才可以获取到ZhouyuFactoryBean这个bean
如下,通过&user就正确打印了:
通过user获取Person 这个bean
注意:通过getBean("user",Person.class)拿到的bean对象和在如下方法中打印出来的bean对象是同一个,如下
当然这里继承了FactoryBean的类定义bean也可以不需要编程式定义,也可以通过注解的方式
注释掉这个编程式定义:
直接在ZhouyuFactoryBean上面加component注解
这么写不对,到时候通过方法getBean("user",Person.class)获取bean时会找不到
应该在component注解加上bean注册的名字:
开启扫描:
加载这个配置类:
总结FactoryBean的方式:
实际上通过FactoryBean方式是间接的定义bean,为什么是间接呢,因为我们实际是在定义这个ZhouyuFactoryBean的时候,帮我们定义了person这个bean,这里定义了两个bean。
7.supplier方式
如下方式,直接通过applicationContext.registerBean(User.class)的方式去注册bean也是可以的,其实这种方式也是beanDefintion的方式,可以点进去看看源码
点进去看源码:
其实就是把这个类传进来后,然后生成 beanDefintion
然后注册进去
也就是说我们可以自己省略生成beanDefintion的步骤,applicationContext.registerBean(User.class)帮我们做了这些事情
定义了User的bean,spring默认生成的名字就是user(小写),可以通过user去获取值
此时去获取这个bean对象的属性,打印出来是null
可以怎么去复制呢?
进入这个方法的源码看看:
如下,有一个supplier,我们可以传这个参数进去
传参如下:
此时打印name就是xxxx了。
这也是一种定义bean的方式