文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

一:对象,JavaBean,SpringBean的区别

1.什么是JavaBean

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



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有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;

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;

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;

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;

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;

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;

public class Person {
}

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


package org.example.bean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@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;

@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;

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;

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;

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,很多情况下底层其实用的都是一样的东西,只是提供了不同的使用方式,具体可以通过源码查看。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯