IOC容器

IOC容器

依赖注入

实体类:

public class User {
    private int id;
    private String name;
    private String password;
   //get  set 构造函数省略
} 

方式一:基于构造函数的依赖注入

  • 构造函数参数类型匹配

    <bean id="user" class="cn.gbl.pojo.User">
        <constructor-arg type="int" value="1"/>
        <constructor-arg type="java.lang.String" value="xxgbl"/>
        <constructor-arg type="java.lang.String" value="1234"/>
    </bean>
    

    测试:

    public void Hello(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
    //结果
    User{id=1, name='xxgbl', password='1234'}
    
  • 构造函数参数索引

    <bean id="user1" class="cn.gbl.pojo.User">
        <constructor-arg index="0" value="2"/>
        <constructor-arg index="1" value="gbl"/>
        <constructor-arg index="2" value="4321"/>
    </bean>
    

    测试:

    @Test
    public void Hello(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user1 = context.getBean("user1", User.class);
        System.out.println(user1);
    }
    //结果
    User{id=2, name='gbl', password='4321'}
    
  • 构造函数参数名称

    <bean id="user2" class="cn.gbl.pojo.User">
        <constructor-arg name="id" value="3"/>
        <constructor-arg name="name" value="xxxx"/>
        <constructor-arg name="password" value="3333"/>
    </bean>
    

    测试:

    @Test
    public void Hello(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user2 = context.getBean("user2", User.class);
        System.out.println(user2);
    }
    //结果
    User{id=3, name='xxxx', password='3333'}
    

方式二:基于Setter的依赖注入(重点)

实体类:

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Set<String> games;
    private Map<String,String> card;
    private Properties info;
    //get  set 构造函数省略
}
public class Address {
    private String country;
    private String city;
    //get  set 构造函数省略
}

set注入:

<bean id="student" class="cn.gbl.pojo.Student">
    <!-- -->
    <property name="name" value="张三"/>
    <!--bean注入 -->
    <property name="address" ref="address"/>
    <!--数组注入 -->
    <property name="books">
        <array>
            <value>Java</value>
            <value>SSM</value>
            <value>vue</value>
        </array>
    </property>
    <!--list注入 -->
    <property name="hobbies">
        <list>
            <value>吃</value>
            <value>喝</value>
            <value>玩</value>
            <value>乐</value>
        </list>
    </property>
    <!--set注入 -->
    <property name="games">
        <set>
            <value>lol</value>
            <value>cs</value>
            <value>yys</value>
        </set>
    </property>
    <!--map注入 -->
    <property name="card">
        <map>
            <entry key="身份证" value="111111"/>
            <entry key="银行卡" value="222222"/>    
        </map>
    </property>
    <!--properties注入 -->
    <property name="info">
        <props>
            <prop key="user">xxgbl</prop>
            <prop key="password">1234</prop>
        </props>
    </property>
</bean>
<bean id="address" class="cn.gbl.pojo.Address">
    <property name="city" value="上海"/>
    <property name="country" value="中国"/>
</bean>

测试:

@Test
public void Hello(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student);
}
//结果
Student{
    name='张三',
    address=Address{country='中国', city='上海'},
    books=[Java, SSM, vue],
    hobbies=[吃, 喝, 玩, 乐], 
    games=[lol, cs, yys],
    card={身份证=111111, 银行卡=222222}, 
    info={password=1234, user=xxgbl}
}

拓展:也可以使用p:namespace和c:namespace注入(看官方文档,在此不多做赘述)

自动装配

上述实现依赖注入的方式都是手动进行注入的,spring提供了自动装配机制。

实体类:

public class Cat {
    private String name;
    //get  set 构造函数省略
}

public class Dog {
    private String name;
   //get  set 构造函数省略
}

public class People {
    private Cat cat;
    private Dog dog;
    private String name;
    //get  set 构造函数省略
}

方式一:基于xml的自动装配

  • byName

    <bean id="cat" class="cn.gbl.pojo.Cat">
        <property name="name" value="Jack"/>
    </bean>
    <bean id="dog" class="cn.gbl.pojo.Dog">
        <property name="name" value="Tony"/>
    </bean>
    <bean id="people" class="cn.gbl.pojo.People" autowire="byName">
        <property name="name" value="xxgbl"/>
    </bean>
    

    测试:

    @Test
    public void people(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        People people = context.getBean("people", People.class);
        System.out.println(people);
    }
    
    //结果
    People{name=xxgbl, cat=Cat{name='Jack'}, dog='Dog{name='Tony'}'}
    
  • byType

    <bean id="cat" class="cn.gbl.pojo.Cat">
        <property name="name" value="Jack"/>
    </bean>
    <bean id="dog" class="cn.gbl.pojo.Dog">
        <property name="name" value="Tony"/>
    </bean>
    <bean id="people" class="cn.gbl.pojo.People" autowire="byType">
        <property name="name" value="xxgbl"/>
    </bean>
    

注意:

  • 使用byName时,必须保证bean的id是唯一的。
  • 使用byType时,必须保证bean的class是唯一的。

方式二:基于注解的自动装配

  • @Autowired

    在配置文件中加入注解支持:

    <?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/>
    
        <beans>
            <bean id="cat" class="cn.gbl.pojo.Cat">
                <property name="name" value="Jack"/>
            </bean>
            <bean id="dog" class="cn.gbl.pojo.Dog">
                <property name="name" value="Tony"/>
            </bean>
            <bean id="people" class="cn.gbl.pojo.People">
                <property name="name" value="xxgbl"/>
            </bean>
        </beans>
    </beans>
    

    在实体类中添加注解:

    public class People {
        private String name;
        @Autowired
        private Cat cat;
        @Autowired
        private Dog dog;
    }
    

    测试:

    @Test
    public void people(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        People people = context.getBean("people", People.class);
        System.out.println(people);
    }
    
    //结果
    People{name=xxgbl, cat=Cat{name='Jack'}, dog='Dog{name='Tony'}'}
    

    @Autowired有一个required 属性默认为true,将@Autowired(required = false)设为flase,字段可以为空。

  • @Resource

    public class People {
        @Resource
        private Cat cat;
        @Resource
        private Dog dog;
        private String name;
    }
    

注意:

​ @Autowired通过byType的方式实现。

​ @Resource通过byName的方式实现,如果找不到名字,就会去找类型。

使用注解开发

在spring配置文件中增加注解支持:

<?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">
    
    <!--扫描 cn.gbl 下的注解,此包下的注解生效   -->
    <context:component-scan base-package="cn.gbl"/>
    <context:annotation-config/>
</beans>

在类中添加注解:

@Component //等价于<bean id="user" class="cn.gbl.pojo.User"/>相当于在配置文件中注入了一个bean
public class User {
    @Value("xxgbl")
    private String name;
    //get set 构造函数省略
}
  1. 注册bean

    • pojo:实体类中用@Component

    • dao:dao层用@Repository

    • service:service层用@Service

    • controller:controller层用@Controller

    它们作用都是一样的,都是向配置文件中注册bean,只不过是每一层的名字不一样。

  2. 属性注入

    @Value(""):使用@Value("")注入属性值。

  3. bean作用域:

    @Scope():使用@Scope():修改bean的作用域。

使用Java代码配置Spring

实体类:

@Component
public class User {
    @Value("xxgbl")
    private String name;
}

配置类:相当于配置文件

@Configuration
public class UserConfig {
    @Bean //相当于将User类注入到配置文件,方法名就是bean的名字,相当于id
    public User getUser(){
        return new User();
    }
}

测试:

@Test
public void people(){
    ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
    User user =  context.getBean("getUser",User.class);
    System.out.println(user);
}

//结果
User{name='xxgbl'}
posted @ 2021-01-31 14:08  xxgbl  阅读(74)  评论(0)    收藏  举报