本文编写于 126 天前,最后修改于 124 天前,其中某些信息可能已经过时。

Bean Scopes (作用域)

关于单例和原型的图片我懒得从本地拿了,详情请看官方文档,俩图概括https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/core.html#beans-factory-scopes-prototype 1.5.1

1.单例模式

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

2.原型模式

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

每次从容器中get都会产生一个新对象

其他的看官网

Bean的自动装配

首先我们来看一下尚未使用自动装配的样子

public class Cat {
    public void shout(){
        System.out.println("miao~");
    }
}
public class Dog {
    public void shout(){
        System.out.println("wang~");
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class People {
    private String name;
    private Dog dog;
    private Cat cat;
}
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="com.springagain01.pojo.Cat"/>
    <bean id="dog" class="com.springagain01.pojo.Dog"/>

    <bean id="people" class="com.springagain01.pojo.People">
        <property name="name" value="烟雀"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>


</beans>
public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        People people = context.getBean("people", People.class);
        people.getCat().shout();
        people.getDog().shout();
        System.out.println(people.getName());
    }
}

输出结果:

miao~
wang~
烟雀

通过ref可以加载bean,但是如果要加载许许多多的bean这显然不是一个好方法。官方给咱们推荐了autowire方法可以完美的解决这个问题。

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="com.springagain01.pojo.Cat"/>
    <bean id="dog" class="com.springagain01.pojo.Dog"/>

    <bean id="people" class="com.springagain01.pojo.People" autowire="byName">
        <property name="name" value="烟雀"/>

    </bean>


</beans>

可以看出来在bean标签中加入了autowire方法,它有两种值,一种是byName,另一种也是byName,咳咳当然不可能,另一种是byType;

  • byName的时候,需要保证所有的bean id唯一,并且这个bean需要和自动注入的属性的set方法一致。
  • byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性一致。

关于注解的自动装配@Autowired与@Resource

注解可以忽略set方法,因为使用反射来实现,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName

@Autowired与在xml中寻找上下文匹配的差不多,不过它需要显示的在需要装配的代码上添加。我们可以使用@rQualifier(value = xxx)来给类起别名

@Nullable字段标记这个注解后,说明这个字段可以为null

@Resource同样是自动装配,关于二者的区别我们可以在下文中总结。

@Autowired通过byType的方式实现,必须要求这个对象存在(最常用,springboot天天用。。)

@Resource(据说在11被废弃,因为没有11我也没有考证)通过byName的方式实现,如果找不到名字,则通过byType实现!若两个都找不到就报错

哈~好困