Spring IOC/DI

本文详细介绍了Spring框架中的IOC(控制反转)和DI(依赖注入)原理,并演示了如何在Spring环境中搭建应用,包括配置文件的编写、对象的创建与注入等多种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IOC[ Inversion of controller ] 控制反转 

DI [Dependency Injection]  依赖注入

IOC 能够做的事情 由程序员主动通过 new 实例化对象事情转交给 Spring 负责 ,控制反转中反转指的是转交给 Spring 负责

DI   当一个类(A)中需要依赖另一个类(B)对象时,把 B 赋值给 A 的过 程就叫做依赖注入

Spring 环境搭建  四个核心包以及loggin日志包

  

新建spring配置文件 applicationContext.xml 【文件名和路径可以自定义】

该文件中配置的对象最终被加载到了ApplicationContext容器中

说明:Spring配置文件是基于schema  该schema 文件扩展名为 xsd,把 schema 理解成 DTD 的升级版,比 DTD 具备更好的扩展性,每次引入一个 xsd 文件是一个 namespace(xmlns)

配置文件中只需要引入基本 schema  通过bean标签 创建对象  该配置文件被加载时创建对象

<?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
">
    <!-- id 表示获取到对象标识
          class 创建哪个类的对象
    -->
    <bean id="user" class="com.xt.a_create.Users"></bean>


</beans>

测试代码

public static void main(String[] args) {
        //实例化SpringIOC容器  加载spring配置文件  第二个参数是读取当前类同包下的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml",Test.class);
        getBean("<bean>标签 id 值",返回值类型);如果没有第二个参数, 默认是 Object
        Users user = ac.getBean("user", Users.class);
        System.out.println( user );

        //getBeanDefinitionNames(),Spring 容器中目前所有管理的所有
        String[] beanNames = ac.getBeanDefinitionNames();
        for (int i = 0; i < beanNames.length; i++) {
            System.out.println( beanNames[i]);
        }
}

创建对象的多种方式

通过构造方法创建

1 无参构造创建:默认情况.

2 有参构造创建:需要明确配置

  2.1 需要在类中提供有参构造方法

  2.2 在 applicationContext.xml 中设置调用哪个构造方法创建 对象

   index : 参数的索引,从 0 开始 

   name: 参数名

   type:类型(区分开关键字和封装类 int 和 Integer)

 <!--  指定构造方法创建对象 -->
 <bean id="user" class="com.xt.a_create.Users">
        <constructor-arg  name="userId" value="10" type="int"></constructor-arg>
        <!-- <constructor-arg  name="userName" value="张三" type="java.lang.String"></constructor-arg> -->
        <!-- ref 引入另外的bean  value 基本数据类型或String 等 -->
        <constructor-arg ref="nameValue"></constructor-arg>
</bean>

<!-- 创建 String 的实例对象 -->
<bean id="nameValue" class="java.lang.String">
        <constructor-arg index="0" value="李四"></constructor-arg>
</bean>

实例工厂

  1 工厂设计模式:帮助创建类对象.一个工厂可以生产多个对象.

  2 实例工厂:需要先创建工厂,才能生产对象

  必须要有一个实例工厂

public class UserFactory {

    //工厂方法
    public Users getUserInstance(){
        return new Users();
    }

    //静态方法
    public static Users getUsersInstances(){
        return new Users();
    }
}

在 applicationContext.xml 中配置工厂对象和需要创建的 对象

 <!-- 配置 工厂类 -->
 <bean id="userFactory" class="com.xt.a_create.UserFactory"></bean>
 <!-- 通过工厂类调用 工厂方法获取 对象 -->
 <bean id="user" factory-bean="userFactory" factory-method="getUserInstance"></bean>

3.静态工厂 [不需要创建工厂,快速创建对象]

<bean id="getUsers" class="com.xt.entity.UserFactory" factory-method="getUsersInstances"></bean>

二:处理对象依赖关系[注入]

实体类

public class Users {
    private int userId;
    private String userName;
    private Set<String> sets ;
    private List<String> list;
    private String [] arrs ;
    private Map<String,Object> map ;
    private Properties prop ;

    public Properties getProp() {
        return prop;
    }

    public void setProp(Properties prop) {
        this.prop = prop;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public String[] getArrs() {
        return arrs;
    }

    public void setArrs(String[] arrs) {
        this.arrs = arrs;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSets() {
        return sets;
    }

    public void setSets(Set<String> sets) {
        this.sets = sets;
    }

    public Users() {
        System.out.println("无参构造");
    }

    public Users(int userId,String userName) {
        super();
        this.userId = userId;
        this.userName = userName;
        System.out.println("有参构造 id  name ");
    }

    public Users(String userName,int userId) {
        super();
        this.userId = userId;
        this.userName = userName;
        System.out.println("有参构造 name id   ");
    }

    @Override
    public String toString() {
        return "Users{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", sets=" + sets +
                ", list=" + list +
                ", arrs=" + Arrays.toString(arrs) +
                ",map= "+map+
                ",pro="+prop+
                '}';
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

1.构造方法模式

<bean id="user" class="com.xt.a_create.Users">
    <!--<property name="userId" value="100" ></property>
        <property name="userName" value="张三"></property>-->
    <!-- 等同于 -->
        <property name="userName">
            <value>张三</value>
        </property>
        <property name="userId">
            <value>100</value>
        </property>
</bean>

2.set方法注入值 [普通属性  集合属性(list,map,property)]

 

    <!-- set集合 -->
        <property name="sets">
            <set>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </set>
        </property>

        <!-- list集合 -->
        <property name="list">
            <list>
                <value>网吧</value>
                <value>手机</value>
                <value>电脑</value>
            </list>
        </property>

        <!-- 数组-->
        <property name="arrs">
            <array>
                <value>张</value>
                <value>王</value>
                <value>李</value>
            </array>
        </property>

        <!-- map集合 -->
        <property name="map">
            <map>
                <entry key="en" value="england"></entry>
                <entry key="ch" value="china"></entry>
                <entry key="jp" value="japan"></entry>
            </map>
        </property>

        <!-- properties 类-->
        <property name="prop">
            <props>
                <prop key="user" >root</prop>
                <prop key="pwd" >123456</prop>
            </props>
        </property>

3.内部bean

<bean id="userService" class="com.xt.a_create.UserService">
        <!-- 成员属性 对象类型  提供 set方法 -->
        <property name="userDao">
            <bean id="userDao" class="com.xt.a_create.UserDao"></bean>
        </property>
 </bean>

4.p名称空间

引入p名称空间 

    <bean id="userDao" class="com.xt.a_create.UserDao"></bean>
    <!-- 通过 p:属性-ref 引入 一个 bean -->
    <bean id="userService" class="com.xt.a_create.UserService" p:userDao-ref="userDao"></bean>

5.自动装配

<bean id="userDao" class="com.xt.a_create.UserDao"></bean>
    <!-- autowire 自动装配
        byName  根据名称自动装配,会在容器中找指定名称的对象,注入到set方法的参数中
        byType  根据类型自动装配,要确保该类型对应的对象在IOC容器中 唯一,否则报错
    -->
<bean id="userService" class="com.xt.a_create.UserService" autowire="byName"></bean>

注解方式

加入 context 命名空间

applicationContext.xml中开启注解

<!-- 开启注解  base-package 指定的包扫描注解-->
<context:component-scan base-package="com.xt.a_create"></context:component-scan>
@Component//加入到IOC容器 默认名称是该类的第一个字母小写,跟后续
public class UserService {
    @Resource//会根据指定的名称去IOC容器中找对应的对象注入
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void save(){
        userDao.save();
    }
}

常用的注解

@Component 标识一个组件[类],把当前容器加入到IOC容器 名称默认类名第一个字母小写
@Component(name="") 指定加入IOC容器组件类的名称
@Repository 标识为一个持久层组件
@Service    标识为一个业务逻辑层组件
@Controller 标识为一个控制层组件 [web层]
@Resource  
    1.根据属性名称 会去IOC容器找对象自动注入,找到注入
    2.如果名称没找到,再根据类型找 找到注入[如该类型多个,报错]
@Resource(name="") 根据指定的名称去容器中找
@Autowired 自动装配

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值