好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

一:对象,JavaBean,SpringBean的区别

1.什么是JavaBean

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**

  * @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依赖包

?

1

2

3

4

5

6

<!-- 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文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<? 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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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 + '\ '' +

                 '}' ;

     }

}

运行测试类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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标签

?

1

2

3

4

5

6

7

8

9

10

11

12

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对象

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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类

?

1

2

3

4

5

6

7

8

package org.example.bean;

import org.springframework.stereotype.Component;

/**

  * @author yzh

  * @date 2021/4/29 10:00

  **/

public class Person {

}

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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"),目的是为了扫描包下的注解

?

1

2

3

4

5

6

7

8

9

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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方法可以看出来!!

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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接口方法如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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

查看更多关于JavaBean和SpringBean的区别及创建SpringBean方式的详细内容...

  阅读:12次