Loading

Spring学习-IOC容器

Spring学习-IOC容器

通过XML管理Bean对象

无参构造器

// 接口
public interface Service{
      void doService();
}

// 实现类

public class ServiceImpl implements Service{
      void doService()
      {
            System.out.println("来自ServiceImpl");
      }
}

XML文件配置:

<bean id="serviceImpl" class="com.example.demo.ServiceImpl"/>

调用:

// 通过xml文件获取上下文
ApplicationContext context =  new ClassPathXmlApplicationContext("application-context.xml");

// 从ioc容器中获取bean对象
Service bean = context.getBean("serviceImpl");

// 调用对应的方法
bean.doService();

有参构造器

public class ServiceImplWithArgs implements Service{
      String name;
      int value;
      ServiceImplWithArgs(String name, int value){
            this.name = name;
            this.value = value;
      }

      void doService(){
            System.out.println("来自ServiceImplWithArgs");
      }
}

XML文件:

<!--方式一:通过指定变量名进行注入-->
<bean id="serviceImplWithArgs" class="com.example.demo.ServiceImplWithArgs">
      <constructor-arg name="name" value="名字"/>
      <constructor-arg name="value" value="10"/>
</bean>

<!--方式二:通过索引进行注入-->
<bean id="serviceImplWithArgs" class="com.example.demo.ServiceImplWithArgs">
      <constructor-arg index="0" value="名字"/>
      <constructor-arg index="1" value="10"/>
</bean>

属性注入

java代码:

public class MyBean{
      private String var1;
      private int val2;
      private String[] array;
      private List<String> list;
      private Set<String> set;
      private Map<String, Integer> map;
      private Properties properties;
      private String var3;
      // 省略对应的setter和getter方法
}

XML文件

<bean id = "mybean" class="com.example.demo.MyBean">

      <!--注入String类型变量-->
      <property name="var1" value="test"/>

      <!--注入int类型变量-->
      <property name="val2" value="1"/>

      <!--注入数组类型变量-->
      <property name="array">
            <array>
                  <value>array1</value>
                  <value>array2</value>
            </array>
      </property>
      
      <!--list注入-->
      <property name="list">
            <list>
                  <value>list1</value>
                  <value>list2</value>
            </list>
      </property>
      
      <!--map注入-->
      <property name="map">
            <map>
                  <entry key="key1" value="1"/>
                  <entry key="key2" value="2"/>
                  <entry key="key3" value="3"/>
            </map>
      </property>

      <!--properties注入-->
      <property name="properties">
            <props>
                  <prop key="name">myName</prop>
                  <prop key="age">10</prop>
            </props>
      </property>

      <!--null注入-->
      <property name="var3">
            <null/>
      </property>
</bean>

bean生命周期

Spring中默认为单例模式创建bean对象,所以存在线程安全问题。

解决:

  1. 将bean设置为原型模式prototype
  2. 将有线程安全问题的字段设为ThreadLocal变量

XML文件

<!--原型模式,每次获取bean时为不同的对象-->
<bean id="local" class="com.example.demo.MyBean" scope="prototype"/>

<!--单例模式,每次获取bean为相同的对象-->
<bean id="mybean" class="com.example.demo.MyBean" scope="singleton"/>

bean的自动装配

  1. 通过name进行自动装配
  2. 通过type进行自动装配

XML文件

<!--根据变量名进行自动装配-->
<bean id="bean" class="com.example.demo.MyBean" autowire="byName"/>

<!--根据变量类型进行自动装配-->
<bean id="bean" class="com.example.demo.MyBean" autowire="byType"/>

Spring自动装配Autowired

基于XML文件的自动装配

XML文件:"applicationcontext.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
      
      <!--注解开启-->
    <context:annotation-config/>
      
      <!--扫描指定路径下的组件,托管bean,完成自动装配-->
    <context:component-scan base-package="com.example.demo"/>

</beans>

java文件

@Component
public class Node{
      @Value("default value")
      private String value;
}

@Component
@Data
public class Tree{
      @Autowired
      private Node node;
}

// 测试类
public class MyTest{
      @Test
      public void test(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
            Tree tree = context.getBean(Tree.class);
            System.out.println(tree.getNode().value);
      }
}

注:通过XML完成自动装配的注意事项:

  1. 在xml文件中开启注解<context:annotation-config/>
  2. 在xml文件中开启自动装配指定路径的所有组件<context:component-scan base-package="com.example.demo"/>
  3. 在组件类中加上注解@Component
  4. 在需要自动装配的字段上使用注解@Autowired完成自动装配

类似于@Component的注解:都是将指定的类注册到Spring容器中

  1. Dao层:@Repository
  2. Service层:@Service
  3. Controller层:@Controller

自动装配的注解

  1. @Autowired:用于类中需要自动装配的字段
  2. @Resource:通过名字和类型进行自动装配
  3. @Nullable:用在参数列表中,表示该参数可为null

作用域:加在类名上
@Scope("singleton"):指定为单例
@Scope("prototype"):指定为原型

基于JavaConfig类完成自动装配

配置类

@Component // 配置类需要注册为组件
@ComponentScan("com.example.demo") // 扫描指定路径下的组件
public class MyConfig{
      
}

需要Spring托管的类

@Component
@Data
public class Node{
      
      @Value("default value")
      private String value;
}

需要自动装配的类

@Component
public class Tree{
      @Autowired // 实现自动装配
      private Node node;

      public void print()
      {
            System.out.println(node.getValue());
      }
}

测试类

public class MyTest{
      @Test
      public void test()
      {
            ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); // 加载配置类
            Tree tree = context.getBean(Tree.class); // 通过指定类的class获取bean对象
            // Tree tree = (Tree)context.getBean("tree"); // 通过类名也可以获取对应的bean对象
            tree.print();
      }
}
posted @ 2020-08-06 20:05  战五渣渣渣渣渣  阅读(105)  评论(0编辑  收藏  举报