软件编程
位置:首页>> 软件编程>> java编程>> JavaBean和SpringBean的区别及创建SpringBean方式

JavaBean和SpringBean的区别及创建SpringBean方式

作者:丶_62f3  发布时间:2022-05-23 03:32:14 

标签:JavaBean,SpringBean

一:对象,JavaBean,SpringBean的区别

1.什么是JavaBean

javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问


/**
* @author yzh
* @date 2021/4/29 8:42
**/
public class User {
   //javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问
   private String name;
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
}

2.什么是SpringBean

SpringBean是受Spring管理的对象,所有能受Spring管理的对象都可以是SpringBean

3.SpringBean和JAVABean的区别

  • 用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处不在,任何组件都可以被称为bean

  • 写法不同:传统javabean作为值对象,要求每个属性都提供getter和setter方法;但spring中的bean只需为接受设值注入的属性提供setter方法

生命周期不同:传统javabean作为值对象传递,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行为

二:如何定义一个SpringBean

准备工作:引入Spring依赖包


<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>5.2.14.RELEASE</version>
</dependency>

1.通过ClassPathXmlApplicationContext

通过ClassPathXmlApplicationContext需要指定configLocation,所有我们现在resources目录下新建一个Spring.xml文件


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
   <!-- 使用设值注入方式装配实例 -->
   <bean id="user1" class="org.example.bean.User">
       <property name="name" value="zhangsan" />
   </bean>
   <!-- 使用构造方法装配实例 -->
   <!--使用构造方法装配需要在相应类提供构造函数-->
   <bean id="user2" class="org.example.bean.User">
       <constructor-arg index="0" value="lisi" />
   </bean>
</beans>

同时相应对象重写toString方法,便于更好观察user1和user2


package org.example.bean;
/**
* @author yzh
* @date 2021/4/29 8:42
**/
public class User {
   //javaBean要求所有属性为私有,该类必须有一个公共无参构造函数,private属性必须提供公共的Getter setter给外部访问
   private String name;
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public User(String name) {
       this.name = name;
   }
   public User() {
   }
   @Override
   public String toString() {
       return "User{" +
               "name='" + name + '\'' +
               '}';
   }
}

运行测试类


package org.example.bean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {
       ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
       classPathXmlApplicationContext.setConfigLocation("Spring.xml");
       classPathXmlApplicationContext.refresh();
       User user1 = classPathXmlApplicationContext.getBean("user1",User.class);
       System.out.println(user1);
       User user2 = classPathXmlApplicationContext.getBean("user2", User.class);
       System.out.println(user2);
   }
}

运行结果如下

User{name='zhangsan'}

User{name='lisi'}

2.通过AnnotationConfigApplicationContext底层

也是通过BeanDefinition实现

*@Bean@Component@Service@Controller都可以;一般@Service用于Service层,@Controller用于Controller层,此处以@Bean为例

新建一个Config类,并给User打上@Bean标签


package org.example.bean;
import org.springframework.context.annotation.Bean;
/**
* @author yzh
* @date 2021/4/29 9:20
**/
public class Config {
   @Bean
   public User user(){
       return  new User();
   }
}

通过AnnotationConfigApplicationContext获取bean,并打印bean对象


package org.example.bean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {
       AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
       annotationConfigApplicationContext.register(Config.class);
       annotationConfigApplicationContext.refresh();
       User user = annotationConfigApplicationContext.getBean("user",User.class);
       System.out.println(user);
   }
}

运行结果

User{name='null'}

3.通过BeanDefinition


package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
       //定义一个Bean
       beanDefinition.setBeanClass(User.class);
       //把生成的Bean注册到容器中
       annotationConfigApplicationContext.refresh();
       annotationConfigApplicationContext.registerBeanDefinition("userTest",beanDefinition);
       User userTest = annotationConfigApplicationContext.getBean("userTest", User.class);
       System.out.println(userTest);
   }
}

运行结果

User{name='null'}

4.通过FactoryBean

4.1通过FactoryBean与注解方式

首先新建一个Person类


package org.example.bean;
import org.springframework.stereotype.Component;
/**
* @author yzh
* @date 2021/4/29 10:00
**/
public class Person {
}

然后新建一个PersonFactoryBean类,并实现FactoryBean接口,重写其方法,为其打上@component注解, 此处和在Person类上打注解是同一效果


package org.example.bean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* @author yzh
* @date 2021/4/29 10:01
**/
@Component("person")
public class PersonFactoryBean implements FactoryBean {
   @Override
   public Object getObject() throws Exception {
       return new Person();
   }
   @Override
   public Class<?> getObjectType() {
       return Person.class;
   }
}

其次添加一个Config类打上@ComponentScan("org.example.bean"),目的是为了扫描包下的注解


package org.example.bean;
import org.springframework.context.annotation.ComponentScan;
/**
* @author yzh
* @date 2021/4/29 9:20
**/
@ComponentScan("org.example.bean")
public class Config {
}

最后通过AnnotationConfigApplicationContext获取Bean


package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {
        //Config类为包扫描配置类
       AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
       Person person = annotationConfigApplicationContext.getBean("person", Person.class);
       System.out.println(person);
   }
}

运行结果

org.example.bean.Person@28ac3dc3

4.2通过Factory和BeanDefinition

1.同4.1一样新建一个Person类

2.同4.1一样新建一个PersonFactoryBean类,实现FactoryBean接口,但是不打注解

3.通过BeanDefinition获取对象

此处和注解生成的差别在于通过BeanDefinition注册的会生成两个Bean对象,一个是person对应的类型是Person,另一个是&person对应的类型是PersonFactoryBean,通过下面代码的getBean方法可以看出来!!


package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
       ////定义一个Bean
       beanDefinition.setBeanClass(PersonFactoryBean.class);
       //把生成的Bean注册到容器中
       //annotationConfigApplicationContext.refresh();
       //此处会生成2个Bean对象 第一个对象为&person对应的类型的PersonFactoryBean 第二个对象为person对应的类型为Person;
       annotationConfigApplicationContext.registerBeanDefinition("person",beanDefinition);
       PersonFactoryBean personFactoryBean = annotationConfigApplicationContext.getBean("&person", PersonFactoryBean.class);
       System.out.println(personFactoryBean);
       Person person = annotationConfigApplicationContext.getBean("person", Person.class);
       System.out.println(person);
   }
}

运行结果如下

org.example.bean.PersonFactoryBean@3aeaafa6

org.example.bean.Person@76a3e297

FactoryBean接口提供三个方法,但是我们重写了两个方法,这是因为另外一个方法是默认实现了的

FactoryBean接口方法如下:


package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
public interface FactoryBean<T> {

String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
   @Nullable
   T getObject() throws Exception;

@Nullable
   Class<?> getObjectType();
   //默认实现方法,是否是单例
   default boolean isSingleton() {
       return true;
   }
}

5.通过Supplier


package org.example.bean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.function.Supplier;
/**
* @author yzh
* @date 2021/4/29 8:45
**/
public class Main {
   public static void main(String[] args) {

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
       annotationConfigApplicationContext.refresh();
       annotationConfigApplicationContext.registerBean(User.class, new Supplier<User>() {
           @Override
           public User get() {
               User user = new User();
               user.setName("123");
               return user;
           }
       });
       User user = annotationConfigApplicationContext.getBean("user", User.class);
       System.out.println(user);
   }
}

bean的注入方式本文只是提供了多种api,很多情况下底层其实用的都是一样的东西,只是提供了不同的使用方式,具体可以通过源码查看。

来源:https://www.jianshu.com/p/2e6e07e59599

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com