精华内容
下载资源
问答
  • 什么bean

    千次阅读 2021-06-20 10:41:25
    什么beanbean是计算机自动生成的类,bean是一个由Spring IoC容器实例化、组装和管理的对象。也就是说,bean并不是程序员编辑的,而是程序运行时,由spring通过反射生成的。在程序中,我们并不使用代码去new一个...

    什么是bean?

    bean是计算机自动生成的类,bean是一个由Spring IoC容器实例化、组装和管理的对象。也就是说,bean并不是程序员编辑的,而是程序运行时,由spring通过反射生成的。在程序中,我们并不使用代码去new一个类(service,dao层等),那么谁来new呢?又是如何new的呢?
    让我们看一下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:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
      
      <bean id="userDao4Mysql" class="com.bjpowernode.spring.dao.UserDao4MySqlImpl"/>
      
      <bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
      
      <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
           
           <constructor-arg ref="userDao4Mysql"/>
           
           <!--
           <constructor-arg ref="usrDao4Oracle"/>
             -->
           <!-- <property name="userDao" ref="usrDao4Oracle"/>-->
      </bean>
    </beans>
    

    以UserDao4MySqlImpl为例,我们在xml中定义了一个bean,名字是userDao4Mysql,然后,给userManager中,注入这个bean就可以了。
    相对应的,代码中,UserManagerImpl要这样使用:

    public class UserManagerImpl implements UserManager {
       // 使用spring已经实例化好并注入的userDao
       private UserDao userDao;
       public UserManagerImpl(UserDao userDao) {
       this.userDao = userDao;
    }
       public void addUser(String username, String password) {
          userDao.addUser(username, password);
       } 
    }
    

    可以看到,我们并没有在UserManagerImpl中去new UserDao(),而是提供了一个有参数的构造方法,接收这个UserDao,而我们xml中的配置,就负责将已经初始化好的userDao4Mysql 传进来。

    注解配置

    @Service
    public class UserManagerImpl implements UserManager {
        
       @Autowired
       private UserDao userDao;
    
       public void addUser(String username, String password) {
          userDao.addUser(username, password);
       }
    }
    

    此时的@Autowired语句,其实就等价于xml中的constructor-arg,@Service就相当于标签。

      <bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
           <constructor-arg ref="userDao4Mysql"/>
      </bean>
    

    此时我们会注意到,这说来说去,好像都还是再说类,难道bean就是类?
    我并不这么理解,我们都知道,spring是通过IOC容器来管理对象的,那么这个IOC容器是个啥呢?IOC的实现远离,就是工厂模式加反射,此时我们引入工厂来进行说明。
    我们来看一个最简单的例子,《大话设计模式》中工厂的例子
    图1:
    在这里插入图片描述

    图2:
    在这里插入图片描述
    图3:
    在这里插入图片描述

    图4:
    在这里插入图片描述

    可以看到,如果我们不使用spring容器,然后A类想使用B类,但是不想自己new的时候,可以通过使用工厂方法的方式来做到。
    再来看一下如果我们使用spring,我们应该怎么写这段代码呢?

    public  interface Operation {
    
        double GetResult(double numberA,double numberB);
    }
    
    
    
    
    @Service
    public class OperationAdd implements Operation{
    
        public double GetResult(double numberA, double numberB) {
            double result = 0;
            result = numberA+numberB;
            return result;
        }
    }
    
    
    
    
    
    @Service
    public class OperationSub implements Operation{
    
        public double GetResult(double numberA,double numberB) {
            double result = 0;
            result = numberA+numberB;
            return result;
        }
    }
    
    
    @Componet
    public class MainTest {
    
        @Autowired
        private Operation operationAdd;
    
        public static void main(String[] args) {
            double a=1;
            double b=2;
            double result=operationAdd.GetResult(a,b);
        }
    }
    

    可以对比看一下,使用spring,比不使用spring,少了很多代码,少的那一部分,就是bean的部分,也就是说,

        @Autowired
        private Operation operationAdd;
    
    //等价于:
      
      <bean id="operationAdd" class="com.example.demo.factorytest.OperationAdd"/>
      
      <bean id="mainTest" class="com.example.demo.factorytest.MainTest">
           
           <constructor-arg ref="operationAdd"/>
      </bean>
    
    //等价于:
    
        class AddFactory:IFactory{
            public Operation CreateOperation(){
                return new OperationAdd();
            }
        }
    

    那么,bean就相当于class AddFactory:IFactory这一层,而为了适用性更广,spring是通过反射来进行new的这个过程的,只要识别到我们打到类上的标签,比如@Service,@Componet等,就会通过反射将类实例化出来,并且统一放到IOC容器(一个map)中管理起来,当发现到@Autowire,@Resource等标签时,就通过名字或者类型将对象从map中拿出来注入进去。

    bean和类是什么关系?
    一个bean,对应一个类。他们是一对一的。

    spring如何管理bean?
    spring的工厂是如何实现的?
    工厂方法的配置文件体现在哪部分?
    为什么类要包装一层?

    展开全文
  • JavaBean,Spring Bean对象的理解

    千次阅读 2020-04-25 19:31:29
    JavaBean,Spring Bean对象什么?现在我们来谈谈什么Bean对象,还得先从JavaBean说起…...


    一、Bean对象

    现在我们来谈谈什么是Bean对象,还得先从JavaBean说起…


    1. JavaBean

    JavaBean 是一种 Java语言写成的可重用组件。写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,long和class方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制发现和操作这些JavaBean 的属性。(这段话太官方,咱看的迷迷糊糊的,举个实例来说)

    Q1:什么是JavaBean?

    1. 所有的类必须放在一个包中;
    2. 所有的类必须声明为public,这样才能够被外部所访问;
    3. 类中所有的属性都必须封装,即:使用private声明;
    4. 封装的属性如果需要被外部所操作,则必须编写对应的settergetter方法;
    5. 一个JavaBean中至少存在一个无参构造方法

    第一个简单JavaBean

    public class User {
        private String name;
        private int age;
        
        public void setName(String name) {
            this.name = name;    
        }   
        
        public void setAge(int age) {
            this.age = age;    
        }
        
        public String getName() {
            return this.name;    
        }
        
        public int getAge() {
            return this.age;    
        }
    }
    

    如果在一个类中只包含属性、settergetter方法,那么这种类就成为简单JavaBean

    对于简单的JavaBean也有几个名词:

    • VO:与简单Java对象对应,专门用于传递值的操作上
    • POJO:简单Java对象
    • TO:传输对象,进行远程传输时,对象所在的类必须实现java.io.Serializable接口。

    为什么要写成JavaBean?

    对于程序员来说,最好的一点就是 JavaBean可以实现代码的重复利用,模块独立,易于维护。

    Bean:在计算机英语中,有可重用组件的含义。

    JavaBean:用java语言编写的可重用组件

    JavaBean > 实体类


    2. Spring Bean

    Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.

    以前我们要用对象是通过自己new来生产的,现在是通过Spring这个工厂来代替我们管理生产,我们来使用。

    对于Spring容器能够生产那些对象,则取决于配置文件中配置。

    对于我们而言,我们使用Spring框架所做的就是两件事:开发Bean、配置Bean。

    对于Spring框架来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法完成“依赖注入”。

    简而言之,Spring Bean是Spring框架在运行时管理的对象。Spring Bean是任何Spring应用程序的基本构建块。使用Spring框架时编写的大多数应用程序逻辑代码都将放在Spring Bean中。


    Spring Bean的管理包括:

    • 创建一个对象
    • 提供依赖项(例如其他Bean,配置属性)
    • 拦截对象方法调用以提供额外的框架功能
    • 销毁一个对象

    3. Bean的定义

    <beans…/>元素是Spring配置文件的根元素,<bean…/>元素是<beans…/>元素的子元素,<beans…/>元素可以包含多个<bean…/>子元素。

    每个<bean…/>元素可以定义一个Bean实例,每一个Bean对应Spring容器里的一个Java实例。

    定义Bean时通常需要指定两个属性:

    id:确定该Bean的唯一标识符,容器对Bean管理、访问、以及该Bean的依赖关系,都通过该属性完成。Bean的id属性在Spring容器中是唯一的。

    class:指定该Bean的具体实现类。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的全限定类名。

    下面是定义一个Bean的简单配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://www.springframework.org/schema/beans"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    	<!-- 定义第一个Bean实例:bean1 -->
    	<bean id="bean1" class="com.Bean1" />
    	
    	<!-- 定义第二个Bean实例:bean2 -->
    	<bean id="bean2" class="com.Bean2" />
    	
    </bean>
    

    Spring容器集中管理Bean的实例化,Bean实例可以通过BeanFactorygetBean(Stringbeanid)方法得到。BeanFactory是一个工厂,程序只需要获取BeanFactory引用,即可获得Spring容器管理全部实例的引用。程序不需要与具体实例的实现过程耦合(这就是用Spring解耦的原理)。

    大部分Java EE应用里,应用在启动时,会自动创建Spring容器,组件之间直接以依赖注入的方式耦合,甚至无须主动访问Spring容器本身。

    当我们在配置文件中通过<bean id=“xxxx” class=“xx.XxClass”/>方法配置一个Bean时,这样就需要该Bean实现类中必须有一个无参构造器。故Spring底层相当于调用了如下代码:

    Xxx = new xx.XxClass()
    

    4. bean标签的属性

    1. id: id是bean的唯一标识符,在Spring容器中不可能同时存在两个相同的id;

    2. class: 类的全限定名(包名+类名)

    3. name: 用法:getBean(“name”),支持设置多个别名,之间用英文逗号分割;

    4. abstract: 设置bean是否为抽象类,默认abstract=“false”,如果设为true,将不能被实例化;

    5. scope: bean的作用范围

    6. destroy-method: 它的作用是在销毁bean之前可以执行指定的方法。注意:必须满足scope=“singleton”,并且destroy方法参数个数不能超过1,并且参数类型只能为boolean。

    7. init-method: 它的作用是在创建一个bean之后调用该方法,初始化方法必须是一个无参方法。

    8. factory-bean和factory-method: 设置了factory-bean属性后,将指定创建bean的工厂类对象,class属性将失效;设置了factory-method属性后,将指定创建bean的工厂方法;

    9. parent: 指定bean的父类,class属性失效。

    5. bean标签的子标签

    <constructor-arg>:构造器参数(顺序注入),此种方式会按照顺序注入构造器的参数。

    <property>:Setter() 注入JavaBean的成员变量


    二、Spring对Bean的管理细节

    1. 创建Bean的三种方式

    I. 使用默认构造函数创建

    在Spring的配置文件中使用Bean标签,配以idclass属性之后,且没有其他属性和标签时。 采用的就是默认构造函数创建Bean对象,此时如果类中没有默认构造函数,则对象无法创建。

    II. 使用普通工厂中的方法创建对象

    使用某个类中的方法创建对象,并存入spring容器

    III. 使用工厂中的静态方法创建对象

    使用某个类中的静态方法创建对象,并存入Spring容器

    2. Bean对象的作用范围

    Bean标签的scope属性:

    作用:用于指定bean的作用范围

    取值: 常用的就是单例的和多例的

    • singleton:单例的(默认值)
    • prototype:多例的
    • request:作用于web应用的请求范围
    • session:作用于web应用的会话范围
    • global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session

    global-session:集群环境是由多个服务器构成,某一个服务器上的session不能够被其他服务器识别。global-session相当于全局变量,在session销毁之前全局有效

    3. Bean对象的生命周期

    单例对象

    • 出生:当容器创建时对象出生
    • 活着:只要容器还在,对象一直活着
    • 死亡:容器销毁,对象消亡
    • 总结:单例对象的生命周期和容器相同

    多例对象

    • 出生:当我们使用对象时Spring框架为我们创建
    • 活着:对象只要是在使用过程中就一直活着
    • 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器GC回收
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--Bean对象默认是单例的-->
        <bean id="userService" class="org.iqqcode.service.impl.UserServiceImpl"/>
            
    </beans>
    

    【参考文章】

    Spring读书笔记-----Spring的Bean之Bean的基本概念

    展开全文
  • 什么Bean

    万次阅读 多人点赞 2018-07-21 21:29:15
    1、Java面向对象对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化);   2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性;   3、规律:凡是子类及带有方法或...

    Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法:

     

    一、Bean是啥

    1、Java面向对象,对象有方法和属性,那么就需要对象实例来调用方法和属性(即实例化);

     

    2、凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性;

     

    3、规律:凡是子类及带有方法或属性的类都要加上注册Bean到Spring IoC的注解;(@Component , @Repository , @ Controller , @Service , @Configration

     

    4、把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了

     

    5、我们都在微博上@过某某,对方会优先看到这条信息,并给你反馈,那么在Spring中,你标识一个@符号,那么Spring就会来看看,并且从这里拿到一个Bean(注册)或者给出一个Bean(使用)

    二、注解分为两类:

    1、一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取Bean;

     

    2、一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的@Autowired , @Resource配合到一起,把对象、属性、方法完美组装。

     

    三、@Bean是啥?

     

    1、原理是什么?先看下源码中的部分内容:

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    Indicates that a method produces a bean to be managed by the Spring container.

     

     <h3>Overview</h3>

     

     <p>The names and semantics of the attributes to this annotation are intentionally

     similar to those of the {@code <bean/>} element in the Spring XML schema. For

     example:

     

     <pre class="code">

         @Bean

         public MyBean myBean() {

             // instantiate and configure MyBean obj

             return obj;

        }</pre>

      意思是@Bean明确地指示了一种方法,什么方法呢——产生一个bean的方法,并且交给Spring容器管理;从这我们就明白了为啥@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了。

     2、记住,@Bean就放在方法上,就是产生一个Bean,那你是不是又糊涂了,因为已经在你定义的类上加了@Configration等注册Bean的注解了,为啥还要用@Bean呢?这个我也不知道,下面我给个例子,一起探讨一下吧:

    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

    28

    29

    30

    31

    32

    33

    34

    3

    package com.edu.fruit;

      //定义一个接口

        public interface Fruit<T>{

            //没有方法

    }

     

    /*

    *定义两个子类

    */

    package com.edu.fruit;

         @Configuration

         public class Apple implements Fruit<Integer>{//将Apple类约束为Integer类型

     

    }

     

    package com.edu.fruit;

         @Configuration

         public class GinSeng implements Fruit<String>{//将GinSeng 类约束为String类型

     

    }

    /*

    *业务逻辑类

    */

    package com.edu.service;

           @Configuration

           public class FruitService {

              @Autowired

              private Apple apple;

              @Autowired

              private GinSeng ginseng;

        //定义一个产生Bean的方法

           @Bean(name="getApple")

           public Fruit<?> getApple(){

           System.out.println(apple.getClass().getName().hashCode);

             System.out.println(ginseng.getClass().getName().hashCode);

           return new Apple();

    }

    }

    /*

    *测试类

    */

    @RunWith(BlockJUnit4ClassRunner.class)

    public class Config {

        public Config(){

            super("classpath:spring-fruit.xml");

        }

        @Test

        public void test(){

            super.getBean("getApple");//这个Bean从哪来,从上面的@Bean下面的方法中来,返回

                                                              的是一个Apple类实例对象

             

        }

    }

    从上面的例子也印证了我上面的总结的内容:

    1、凡是子类及带属性、方法的类都注册Bean到Spring中,交给它管理;

    2、@Bean 用在方法上,告诉Spring容器,你可以从下面这个方法中拿到一个Bean

    展开全文
  • Spring Bean详细讲解 什么Bean?

    万次阅读 多人点赞 2018-11-19 15:45:37
    Spring 容器会自动完成@bean对象的实例化。 创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。 Spring 三种配置方案 1.在XML中进行显示配置 2.使用Java代码进行显示配置 3.隐式的bean...

    什么是Bean?

    Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象。

    Spring 容器会自动完成@bean对象的实例化。

    创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。

    Spring 三种配置方案

    1.在XML中进行显示配置
    2.使用Java代码进行显示配置
    3.隐式的bean发现机制和自动装配
    推荐方式: 3>2>1

    一、自动化装配bean

    1.组件扫描(component scanning):Spring 会自动发现应用上下文中所创建的bean。
    2.自动装配(autowiring):Spring自动满足bean之间的依赖。

    package com.stalkers;
    
    /**
     * CD唱片接口
     * Created by stalkers on 2016/11/17.
     */
    public interface ICompactDisc {
        void play();
    }
    
    package com.stalkers.impl;
    
    import com.stalkers.ICompactDisc;
    import org.springframework.stereotype.Component;
    
    /**
     * Jay同名专辑
     * Created by stalkers on 2016/11/17.
     */
    @Component
    public class JayDisc implements ICompactDisc {
    
        private String title = "星晴";
    
        public void play() {
            System.out.println(title + ":一步两步三步四步,望着天上星星...");
        }
    }
    

    Component注解作用:
    表明该类会作为组件类。

    不过,组件扫描默认是不开启用的,我们还需要显示配置下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。

    1.java code开启组件扫描:
    其中,如果CompoentScan后面没有参数的话,默认会扫描与配置类相同的包

    @Configuration
    @ComponentScan
    public class CDPlayerConfig {
        @Bean
        public ICompactDisc disc() {
            return new JayDisc();
        }
    }
    

    2.xml启动组件扫描

    <?xml version="1.0" encoding="utf-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context.xsd">
        <context:component-scan base-package="com.stalkers.impl"/>
    </beans>

    测试代码

    package com.stalkers;
    
    import com.stalkers.config.CDPlayerConfig;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    /**
     * Created by stalkers on 2016/11/18.
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = CDPlayerConfig.class)
    public class TestPlay {
        @Autowired
        private ICompactDisc jayDisc;
    
        @Test
        public void play() {
            jayDisc.play();
        }
    }
    

    在ComponentScan扫描的包中,所有带有@Component注解的类都会创建为bean

    为组件扫描的bean命名

    Spring应用上下文种所有的bean都会给定一个ID。在前面的例子中,尽管我们没有明确地为JayDisc bean设置ID,但是Spring会默认为JayDisc设置ID为jayDisc,也就是将类名的第一个字母变成小写

    如果想为这个bean设置不同的ID,那就将期望的值传递给@Component注解

    @Component("zhoujielun")
    public class JayDisc implements ICompactDisc {
      ...
    }

    如果不使用@Component注解的话,则使用Java依赖注入规范(Java Dependency Injection)中所提供的@Named注解bean的ID。

    需要引入:

       <dependency>
                <groupId>javax.inject</groupId>
                <artifactId>javax.inject</artifactId>
                <version>1</version>
            </dependency>
    
    @Named("zhoujielun")
    public class JayDisc implements ICompactDisc {
      ....
    }

    设置组件扫描的基础包

    前面再给CDPlayerConfig类设置@ComponentScan,我们并没有设置任何属性,这个时候默认扫描默认包是:CDPlayerConfig类所在包及其包的子包。

    如果是下图这种情况,DisConfig与其这时候就需要设置@ComponentScan的扫描的包。

    image

    @Configuration
    @ComponentScan(basePackages = {"com.stalkers.soundsystem"})
    public class DiscConfig {
    }
    

    basePackages使用的是复数,则意味着可以设置多个基础包。

    但是basePackages后面跟的是String类型,这种类型并不安全。可以使用basePackageClasses有下面这种写法:

    @Configuration
    @ComponentScan(basePackageClasses = {com.stalkers.soundsystem.JayCompactDisc.class})
    public class DiscConfig {
    }

    通过为bean添加注解实现自动装配

    如果所有的对象都是独立的,彼此之间没有任何依赖,那么使用组件扫描就能自动化装配bean。

    但是实际工作中,很多对象会依赖其他对象完成任务。这时候就需要能够将组件扫描得到的bean和他们依赖装配在一起。这就是自动装配(autowiring)

    使用Spring的Autowired

    public interface IMediaPlayer {
        void play();
    }
    @Component
    public class CDPlayer implements IMediaPlayer {
    
        private ICompactDisc cd;
        
        @Autowired
        public CDPlayer(ICompactDisc cd) {
            this.cd = cd;
        }
    
        public void play() {
            System.out.println("cd Play:");
            cd.play();
        }
    }

    CDPlayer类的构造器上添加了@Autowired注解,表明当Spring创建CDPlayerbean的时候,会通过这个构造器来进行实例化

    Autowired的多种方式
    1.构造器注解(constructor)

    2.属性setter注解

    3.field注解

    不管使用上面3中的哪个方法,Spring都会满足声明的依赖。假如有且只有一个bean匹配依赖的话,那么这个bean将会被装配进来。

    如果使用2,3方式注解,有多个bean的话,则用Qualifier指定。

    如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,可以使用

    @Autowired(required = false)
    private IMediaPlayer CDPlayer;

    required=false表示如果没有匹配的话,Spring会让bean处于未装配的样子。使用未装配的属性,会出现NullPointerException

    总结:
    所以在使用开发的时候一般建议使用Resource(package javax.annotation)进行注解。但是Resource不支持构造器注解

    二、通过Java代码装配Bean

    尽管在很多场景下通过组件扫描和自动装配实现Spring的自动化更为推荐,但是有时候行不通。比如引用第三方组件,没办法在它的类上添加@Component及@Autowired。所以就需要JavaConfig或者XML配置

    在进行显示配置的时候,JavaConfig是更好的解决方案。

    JavaConfig与其他的Java代码又有所区别,在概念上它与应用程序中的业务逻辑和领域代码又有所不同。JavaConfig是配置相关代码,不含任何逻辑代码。通常会将JavaConfig放到单独的包中。

    创建JavaConfig类

    @Configuration
    public class CDPlayerConfig {
    }

    使用@Configuration表明CDPlayerConfig是一个配置类

    声明简单的bean

    @Bean
    public IMediaPlayer cdplayer() {
        return new VCDPlayer(new JayCompactDisc());
    }

    @Bean注解会告诉Spring将返回一个对象。

    默认情况下,@Bean的Id与带有@Bean的方法名一样。当然也可以通过@Bean的name属性指定额外的方法名。

    借助JavaConfig注入

    在上面的例子中,初始化个VCDPlayer都需要new一个JayCompactDisc对象。如果其他的对象的也需要JayCompactDisc,所以优化如下:

    @Bean
    public IMediaPlayer cdplayer() {
        return new VCDPlayer(disc());
    }
    
    @Bean
    public ICompactDisc disc() {
        return new JayCompactDisc();
    }

    单独抽出disc()方法,在其方法上加上Bean注解,Spring上加@Bean注解的都是默认单例模式,不管disc()被多个方法调用,其disc()都是同一个实例。

    当然上面的初始化可以优化如下:

    @Bean
    public IMediaPlayer cdplayer(ICompactDisc disc) {
        return new VCDPlayer(disc);
    }

    三、通过XML装配Bean

    在xml配置中,创建一个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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
       
    </beans>

    在使用xml的时候,需要在配置文件顶部声明多个xml模式(XML Schema Definition xsd)文件

    对于我们需要配置bean的则在spring-beans模式中。

    <?xml version="1.0" encoding="utf-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>
    </beans>

    1.借助构造器注入初始化bean

    构造器注入的方案:
    1.元素

    <?xml version="1.0" encoding="utf-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>
        <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer">
            <constructor-arg ref="jayCompactDisc"/>
        </bean>
    </beans>

    2.使用Spring3.0所引入的c-命名空间

    使用c-命名空间,需要引入:

    xmlns:c="http://www.springframework.org/schema/c"
    <?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:c="http://www.springframework.org/schema/c"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="jayCompactDisc" class="com.stalkers.soundsystem.JayCompactDisc"></bean>
        <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:cd-ref="jayCompactDisc">
        </bean>
    </beans>

    解析:c-命名空间的语法:

    c:cd-ref="jayCompactDisc"

    1.c 代表命名空间前缀

    2.cd 代表VCDPlayer类的构造器参数名。当然我们也可以使用参数在整个参数列表的位置 c:_0-ref

     <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="jayCompactDisc">

    使用下划线因为参数不能以数字开头,所以加下划线。

    3.-ref 代表注入bean引用

    4.jayCompactDisc 要注入的bean的id

    注意:

    c-命名需要写在标签内,与constructor-arg写法差别很大

    将字面量注入到构造器中

    上面我们所做的DI通常指的是类型的装配,也就是将对象的引用装配到依赖他们的其他对象中,但是有时候我们传的只是一个字面量值

    public class VaeCompactDisc implements ICompactDisc {
        private String title;
    
        public VaeCompactDisc(String title) {
            this.title = title;
        }
    
        public void play() {
            System.out.println("大家好,我是Vae,下面这首:" + title + "献给大家的");
        }
    }
    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">
    </bean>
    <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc">
        <constructor-arg value="浅唱"></constructor-arg>
    </bean>

    c-命名空间的写法

    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">
    </bean>
    <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc" c:title="城府">
        <!--<constructor-arg value="浅唱"></constructor-arg>-->
    </bean>

    装配集合

    public class VaeCompactDisc implements ICompactDisc {
        private String title;
    
        private List<String> tracks;
    
        public VaeCompactDisc(String title, List<String> tracks) {
            this.title = title;
            this.tracks = tracks;
        }
    
        public void play() {
            System.out.println("大家好,我是Vae,下面这专辑:" + title + "献给大家的");
            for (String s : tracks) {
                System.out.println(s);
            }
        }
    }

    Spring配置使用constructor-arg。而c-命名的是无法使用装配集合的功能

    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" c:_0-ref="vaeCompactDisc">
    </bean>
    <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc">
        <constructor-arg name="title" value="自定义"></constructor-arg>
        <constructor-arg name="tracks">
            <list>
                <value>有何不可</value>
                <value>多余的解释</value>
            </list>
        </constructor-arg>
    </bean>

    2.使用属性Setter方法注入

    public class CDPlayer implements IMediaPlayer {
    
        private ICompactDisc cd;
    
        @Autowired
        public void setCd(ICompactDisc cd) {
            this.cd = cd;
        }
        
        public CDPlayer(ICompactDisc cd) {
            this.cd = cd;
        }
    
        public void play() {
            System.out.println("cd Play:");
            cd.play();
        }
    }
    

    Spring.xml配置里面

    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer">
        <property name="cd" ref="jayCompactDisc"></property>
    </bean>

    元素为属性的Setter方法所提供的功能与元素为构造器所提供的功能是一样的。

    与c-命名空间的类似的作为property的替代方案:p-命名空间。使用p-命名空间需要引入:

    xmlns:p="http://www.springframework.org/schema/p"

    Spring.xml配置如下

    <bean id="cdPlayer" class="com.stalkers.soundsystem.VCDPlayer" p:cd-ref="vaeCompactDisc">

    语法解析:

    p:cd-ref="vaeCompactDisc"

    1.p-:命名空间的前缀

    2.cd:属性名称

    3.-ref:注入bean引用

    4.vaeCompactDisc:所注入的bean的id

    将字面量注入到属性中

    字面量注入到属性与上面将字面量注入到构造方法中方式一样。只不过标签名改成了property。

    装配list也是与上面的构造器的装配list一样。

    虽然我们无法使用c-及p-命名空间装配list,但是我们可以使用

    <bean id="vaeCompactDisc" class="com.stalkers.soundsystem.VaeCompactDisc" c:title="自定义" c:tracks-ref="songs">
    </bean>
    <util:list id="songs">
        <value>有何不可</value>
        <value>多余的解释</value>
    </util:list>

    Spring util命名空间的中的元素:

    元素描述
    util:constant引用某个类型的public static 域
    util:list创建一个java.util.List类型的bean,其中包含值或引用
    util:map创建一个java.util.Map类型的bean,其中包含值或引用
    util:properties创建一个java.util.Properties类型的bean
    util:property-path引用一个bean的属性
    util: set创建一个java.util.Set类型的bean

    在此我向大家推荐一个架构学习交流群。交流学习群号:895244712 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

    四、导入和混合配置

    在Spring应用中,我们可以同时使用自动化和显示配置。

    如果一个JavaConfig配置太臃肿,我们可以把其进行拆分,然后使用@Import将拆分的类进行组合。

    如果希望在JavaConfig里引用xml配置。则可以使用@ImportResource

     

    展开全文
  • Spring源码阅读之bean对象的创建过程

    千次阅读 2020-06-10 23:52:58
    Spring源码阅读之bean对象的创建过程 ​ Spring是通过IOC容器来管理对象的,该容器不仅仅只是帮我们创建了对象那么简单,它负责了对象的整个生命周期-创建、装配、销毁。这种方式成为控制反转(组件对象控制权的...
  • Spring是使用反射创建的对象,而且可以指定对象的生命周期, beanan生命周期 scope控制bean的生命周期,scope的取值有5种取值: 在Spring 2.0之前,有singleton和prototype两种; 在Spring 2.0之后增加另外三种:...
  • 5w字长文带你彻底看懂Spring是怎么创建对象的!附10几张图,在创作这篇文章的过程中给官方提交了两个issue
  • Spring Bean到底是什么?有什么用?

    万次阅读 多人点赞 2019-02-23 22:41:56
    Spring Bean什么?有什么用?Bean在Spring和SpringMVC中随处可见,将这个概念内化很重要,下面分享一下我的想法:一、Bean到底是什么?二.怎么使用beanBean配置Bean的作用域 Bean在Spring和SpringMVC中随处可见,将...
  • Spring中的bean什么

    千次阅读 多人点赞 2020-07-28 17:31:23
    Bean是Spring框架中最核心的两个概念之一(另一个是面向切面编程AOP)。 1 定义 Spring 官方文档对 bean 的解释是: In Spring, the objects that form the backbone of your application and that are managed by ...
  • Spring Bean对象

    千次阅读 2018-02-27 15:08:39
    Bean对象的基本配置 在软件应用中由Spring管理的所有的对象都称之为Bean,我们自己创建 的类假如需要由Spring管理,首先需要对这个类进行配置。 常用的配置方式:1.基于xml进行配置 2.基于注解进行配置 基于xml...
  • Map,Bean对象互相转换

    千次阅读 2019-06-09 09:40:28
    工具类 非常棒的一个工具类 import org.springframework.cglib.beans.BeanMap; import java.util.HashMap;... * Map集合与Bean对象转换 工具类 */ public class BeanMapUtils { /** * 将对象属性转化为map结合 ...
  • Spring之Bean对象的初始化和销毁方法

    千次阅读 多人点赞 2019-03-04 21:19:53
      在Bean对象的完整的生命周期前我们还需要给大家介绍下Bean对象自身初始化及销毁的相关方法。 Bean初始化及销毁方法   在Spring中给我们提供了两种操作的方法, 通过bean标签中的init-method和destroy-method...
  • Spring框架|创建Bean对象的三种方式

    千次阅读 2020-01-25 23:51:47
    文章目录一、无参构造函数(常用)二、静态工厂三、实例工厂(鸡肋)...采用的就是默认构造函数创建bean对象。此时如果类中没有默认构造函数,则对象无法创建。 <bean id="p" class="com.gql.entity.Person">&...
  • 但是很多人不清楚默认情况下,通过@Bean注解声明的Bean的名称是什么? 请问,如下代码声明bean的名称是什么? @Configuration public class LogAutoConfigure { @Bean public Queue queueTest() { return new ...
  • 这样就可以在Servlet中去获取到在Spring中注入的bean对象,通过bean对象就可以获取里面的接口对象等,已经获取到了bean对象,剩下的需要做什么就由自己决定了。 MyServlet servlet = (MyServlet) findBean(...
  • 在Eclipse搭建的Spring开发环境中,使用工厂方式创建Bean对象,将创建的Bean对象输出到控制台。要求如下: 使用静态工厂创建Bean对象。 使用动态工厂创建Bean对象。 实现思路: 在com.mhys.bean包下,创建Card...
  • Java Bean对象复制的三种方式详解

    千次阅读 2020-04-25 22:58:18
    对象的克隆是指创建一个新的对象,且新的对象的状态与原始对象的状态相同且我们对新对象修改时,不影响原对象的状态。 原理如下 clone()是object类的protected 方法,只有类的对象自己可以克隆自己 因此,必须实现...
  • 简介Spring的IOC功能,就是对象的实例化工作,由Spring容器完成. Bean对象注意点 需要无参构造器; 默认情况下,生成的实例为单例; 在配置文件中的<Bean>,其实就是实例. - Spring容器注入Bean对象.1.
  • 11 可用来修改bean对象的BeanPostProcessor11.1 简介BeanPostProcessor是Spring中定义的一个接口,其与之前介绍的InitializingBean和DisposableBean接口类似,也是供Spring进行回调的。Spring将在初始化bean前后对...
  • 通过ApplicationContextFactory获取SpringApplication从而获取bean对象 ApplicationContext applicationContext=ApplicationContextFactory.getApplicationContext(); Clazz clazz = applicationContext.getBean...
  • 父类bean对象拷贝所有值给子类bean对象的两种方案 ** 方法一: 用BeanUtils.copyProperties() , 缺点: 好像不支持Java.util.date 类型的拷贝. 父类Java bean : public class Parents ; 子类Java bean : public class ...
  • 1. 获取bean对象 spring的IOC容器主要通过BeanFactory接口的getBean方法来从IOC容器,即BeanFactory的实现类中获取某个bean对象实例,如下为BeanFactory的getBean方法定义: public interface BeanFactory { .....
  • JAVA中Bean什么

    万次阅读 多人点赞 2019-02-18 22:14:25
    JAVA中Bean什么? 简单笼统的说就是一个类,一个可复用的类。 javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置...
  • 但是这个bean中注入的其他bean或new的对象都为空,代理之后拿不到吗? 为什么?怎么才能获取到呢? ![图片说明](https://img-ask.csdn.net/upload/201804/16/1523860339_822414.png) ![图片说明]...
  • 1.可以通过<...定义的scope属性指定Bean对象的作用域或者使用注解@Scope指定Bean对象的作用域。  2.默认Bean对象的作用域为singleton。   转载于:https://www.cnblogs.com/myhdc/p/8522583.html...
  • json转换成bean对象

    千次阅读 2018-01-05 17:43:52
    fastJson对于json格式字符串的解析主要用到了一下三个类:JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换。JSONObject:fastJson提供的json对象。JSONArray:fastJson提供json数组对象...
  • web项目中获取spring的bean对象

    万次阅读 2016-06-17 15:58:39
    Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中不通过注解的形式(@Resource、@Autowired)获取Spring配置的bean呢?  Spring通过在web.xml 中配置ContextLoaderListener 来加载...
  • SpringBoot中Spring如何自动创建Bean对象

    千次阅读 2019-12-28 19:45:11
    Bean对象:在Spring中交给Spring自动创建,不需要我们手动去new,所创建的对象,都叫Bean对象。 Spring怎么知道什么对象应该交给他创建呢?类的字节码对象上有注解注释时,他所需要创建的对象,都交给spring创建。 ...
  • Spring IOC中的Bean对象

    万次阅读 2020-05-11 16:13:15
    (一)Bean什么 突然发现提到了好多次Bean,居然忘记了讲Bean什么。没事,现在讲也不晚。Java中的Bean是一种规范,是一种特殊的java类。所以我们先来看看Bean的规范。 Bean必须生成public class类。 所有属性...
  • spring boot获取spring容器中的bean对象

    千次阅读 2019-04-28 13:44:10
    * Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContext方法 * @param applicationContext */ @Override public void setApplicationContext(ApplicationContext applicationContext) { if...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 536,894
精华内容 214,757
关键字:

bean对象是什么意思