一、JavaBean和SpringBean区别
其实一个Bean简单理解为就是一个对象,SpringBean是spring所配置的对象,而JAVAbean是JAVA配置的对象
JavaBean是一个属性全部是私有的对象
public class User{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Springbean是spring创建的对象
二、SpringBean创建的六种方式
XML
这是Spring配置SpringBean最基础的方法之一
<bean id="user" class="com.example.spring_deepstd.US.entity.User"></bean>
首先是配置Spring文件
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("Spring.xml");
User user = applicationContext.getBean("user",User.class);
}
再就是拿到容器的方法
1、首先我们会通过ClassPathXmlApplicationContext传递构造参数,向里面传入一个Spring的配置文件。
2、我们会通过user名称来拿到我们刚刚在Spring中配置的Bean
@Bean
AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext();
applicationContext1.register(Config.class);
User user1 = applicationContext1.getBean("createUser",User.class);
首先我们前两行代码与我们XML配置时的第一行代码有相同的语义,都是用来配置Spring容器,将我们的类注册到Spring容器内
public class Config {
@Bean
public Object CreateUser(){
return new User();
}
}
而我们的Config类中的CreateUser方法需要加@Bean注解,表示该方法生成的对象就是Spring中的一个Bean
其中,id就表示方法名,而注册进Spring容器中的类就是返回的类。
@Component
@Component注解应用在需要被注册进Spring容器中的类上
@Component
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
而我们的配置类上需要添加@ConponentScan注解
@ComponentScan("US.entity")
public class Config {
}
此时我们的主方法运行时,会先去找到Config这个类,由于Config类上面添加了@ComponentScan注解,表示需要扫描我们给定路径下的包,此时扫描到User类中添加了@Component注解,表示该类需要被注册进Spring容器中。
此时我们的id值Spring互帮我们自动生成,默认情况就是将类名首字母改成小写。
BeanDefinition
这个类可以理解为描述SpringBean的一个类
public static void main(String[] args) {
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("Spring.xml");
//获取BeanDefinition对象
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
//简单的创建一个Bean
beanDefinition.setBeanClass(User.class);
AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext();
//将BeanDefinition创建到容器对象里面去
applicationContext1.registerBeanDefinition("user",beanDefinition);
User user1 = applicationContext1.getBean("CreateUser",User.class);
}
}
注意:
其实看源码我们可以发现,前三种定义Bean的方法的底层实现都是通过BeanDefinition方法实现,我们又把这种创建Bean的方式叫做编程式定义
FactoryBean
我们还可以通过创建一个特殊的类(实现FactoryBean方法创建Bean)
@Component
public class FactoryBean_test implements FactoryBean {
@Override
public Object getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
这个类之所以特殊就是实现了FactoryBean接口,其中第一个方法返回一个Bean对象实例,第二个方法返回一个Bean的类型。
注意,这个类用来生成一个Bean,但是这个类稀释还没有被注册进Spring在容器中,所以我们需要把FactoryBean_test 也添加到Spring容器中。
public static void main(String[] args) {
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("Spring.xml");
//获取BeanDefinition对象
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
//简单的创建一个Bean
beanDefinition.setBeanClass(FactoryBean_test.class);
AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext();
//将BeanDefinition创建到容器对象里面去
applicationContext1.registerBeanDefinition("user",beanDefinition);
//注意:此时我们注册进Spring中的Bean有些特殊,他实现了两个实际上创建了两个Bean对象,第一个就是我们的FactoryBean_teat,
//还有一个就是我们的User对象
//此时id:&user表示的是FactoryBean_teat,id:user表示的是User对象。
User user1 = applicationContext1.getBean("user",User.class);
}
}
Supplier
最后即使我们比较少见的Supplier方法
applicationContext1.registerBean(User.class,new Supplier<User>(){
@Override
public User get() {
User user = new User();
user.setName("XXXX");
return user;
}
});
User user1 = applicationContext1.getBean("user",User.class);
该方法将我们的User类注册进Spring容器后又提供了另一个Supplier类,用来对类进行一些附加操作(比如像代码中调用User类中的setName方法给name设置初始值)。
总结:
我们Spring中注册Bean的方式多种多样,其中根本的问题就是要将我们的类注册进Spring容器中。
同时,我们的所有方法底层都是基于BeanDefinition类进行操作的,@Component组件表示直接将该类注册为一个Bean,而@Bean组件则是将返回的对象注册进Spring容器中。