NO.7 Spring IOC DI依赖注入(2)

NO.7 Spring IOC DI依赖注入(2)

四:注入集合
在spring IOC 容器中,向bean属性注入集合,也是通过property标签注入 ,不同的集合在注入值时,采用的标签不一样,
如果是list类型,则使用标签

<bean id="class" class="com.xt.spring.ioc.test.Classes">
    <property name="className" value="5班"></property>
    <property name="stuNames">
        <list>
            <value>小强</value>
            <value>小红</value>
            <value>小明</value>
        </list>
    </property>
</bean>

如果是set类型,则使用标签

<bean id="class" class="com.xt.spring.ioc.test.Classes">
    <property name="className" value="5班"></property>
    <property name="scores">
        <set>
            <value>95</value>
            <value>90</value>
            <value>100</value>
        </set>
    </property>
</bean>

如果是map类型,则采用标签, 但是,map的基本元素采用注入, 标签里可以使用多个 作为子标签. 每个条目包含一个键和一个值。

<bean id="class" class="com.xt.spring.ioc.test.Classes">
    <property name="className" value="5班"></property>
    <property name="map">
        <map>
            <entry key="小强" value="1500"></entry>
            <entry key="小红" value="1800"></entry>
            <entry key="小明" value="1000"></entry>
        </map>
    </property>
</bean>

代码复用——若两个类中含有相同的list、set、map,可使用工具标签标签,声明公用集合,需要引入util命名空间及xsd文件。xmlns:util=”http://www.springframework.org/schema/util”
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
使用util:类型 配置一个id属性提供引用,其他配置与原集合标签一样。在使用时,bean属性值内容需要使用ref属性引用公用集合。

<?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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd 
           http://www.springframework.org/schema/util
               http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="class" class="com.xt.spring.ioc.test.Classes">
        <property name="map" ref="stuScoresMap"></property>
    </bean>
    <util:map id="stuScoresMap">
        <entry key="小强" value="1500"></entry>
        <entry key="小红" value="1800"></entry>
        <entry key="小明" value="1000"></entry>
    </util:map>

</beans>

五:p 命名空间
为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。
Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过 元素属性的方式配置 Bean 的属性。
使用 p 命名空间后,基于 XML 的配置方式将进一步简化。
需要声明p命名空间:
xmlns:p=”http://www.springframework.org/schema/p”
使用:
在bean标签内 通过p:属性名 = “属性值”方式向bean属性注入值,如果bean的属性为另外bean的引用,则需要p:属性名-ref=”bean的Id”

<bean id="stu" class="com.xt.spring.ioc.test.Student" p:stuNo="2016123456" p:stuName="小明" p:coll-ref="coll"></bean>
<bean id="coll" class="com.xt.spring.ioc.test.Colledge" >
    <property name="id" value="0"></property>
    <property name="name" value="****学院"></property>
</bean>

六:专项配置专项文件
Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量。

<context:property-placeholder location="classpath:DB.properties"/>

<bean id="dataSource" class="com.xt.spring.ioc.test.DBDataSourse">
    <property name="driverName" value="${driverName}"></property>
    <property name="url" value="${url}"></property>
    <property name="userName" value="${userName}"></property>
    <property name="passwd" value="${passwd}"></property>
</bean>

DB.properties为:(“=”后为属性值)

driverName=
url=
userName=
passwd=

DBDataSourse为

package com.xt.spring.ioc.test;

public class DBDataSourse {
    private String driverName;
    private String url;
    private String userName;
    private String passwd;

    public String getDBConn(){
        System.out.println("获取数据库链接了。。。。");
        return "mysql数据库链接";
    }
    public String getDriverName() {
        return driverName;
    }
    public void setDriverName(String driverName) {
        this.driverName = driverName;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Override
    public String toString() {
        return "DBDataSourse [driverName=" + driverName + ", url=" + url + ", userName=" + userName + ", passwd=" + passwd + "]";
    }
}

七:SpEL表达式
Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL。
SpEL 为 bean 的属性进行动态赋值提供了便利。

Spring EL 支持大多数的数学操作符、逻辑操作符、关系操作符。
 1)关系操作符
包括:等于 (==, eq),不等于 (!=, ne),小于 (<, lt),,小于等于(<= , le),大于(>, gt),大于等于 (>=, ge)
 2)逻辑操作符
包括:and,or,and not(!)
 3)数学操作符
包括:加 (+),减 (-),乘 (*),除 (/),取模 (%),幂指数 (^)。

SpEL作用:
1)通过 bean 的 id 对 bean 进行引用
2)调用方法以及引用对象中的属性
3)计算表达式的值
4)正则表达式的匹配

<bean id="spel" class="com.xt.spring.ioc.test.SpelTest">
    <property name="avgAge" value="#{117/3}"></property>
    <property name="passwd" value="#{dataSourse.passwd}" ></property>
    <property name="dataSourse" value="#{dataSourse}"></property>
    <property name="DBConn" value="#{dataSourse.getDBConn()}"></property>
</bean>

SpelTest为:

package com.xt.spring.ioc.test;

public class SpelTest {
    private int avgAge;
    private String passwd;
    private DBDataSourse dataSourse;
    private String DBConn;

    public int getAvgAge() {
        return avgAge;
    }
    public void setAvgAge(int avgAge) {
        this.avgAge = avgAge;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    public DBDataSourse getDataSourse() {
        return dataSourse;
    }
    public void setDataSourse(DBDataSourse dataSourse) {
        this.dataSourse = dataSourse;
    }
    public String getDBConn() {
        return DBConn;
    }
    public void setDBConn(String dBConn) {
        DBConn = dBConn;
    }

    @Override
    public String toString() {
        return "SpelTest [avgAge=" + avgAge + ", passwd=" + passwd + ", dataSourse=" + dataSourse + ", DBConn=" + DBConn + "]";
    }
}

倘若想要获取工厂创建的对象,同样采用如下方式获取:
DBDataSourse data = ioc0.getBean(“dataSource”,DBDataSourse.class);
SpelTest data = ioc0.getBean(“spel”,SpelTest.class);

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
<think>好的,我现在需要回答用户的问题:“spring依赖注入必须两个对象都处于IOC容器中吗”。首先,我需要回忆Spring依赖注入的基本概念。依赖注入DI)的核心是由Spring容器管理对象的创建和依赖关系,所以通常情况下,被注入的对象(依赖)和注入目标对象都需要在IOC容器中,这样容器才能完成依赖的装配。 首先,用户的问题是问是否两个对象都必须在IOC容器中。我需要明确,依赖注入的前提是目标对象(需要被注入依赖的对象)本身由IOC容器管理,即由容器创建和初始化。而被注入的依赖对象,通常也需要在容器中,这样容器才能将其注入到目标对象中。但可能存在例外情况吗?比如,是否可以注入一个不在容器中的对象? 接下来,我需要考虑Spring的几种依赖注入方式,比如构造器注入、setter注入、字段注入。这些方式都要求目标对象由容器管理,否则容器无法进行注入。例如,如果一个对象不是由Spring创建的(比如通过new关键字手动创建),那么Spring不会自动注入其依赖,因为容器不知道这个对象的存在。 然后,被注入的依赖是否必须在容器中?通常是的,因为Spring需要从容器中获取依赖实例来注入。但如果有特殊情况,比如使用@Bean方法创建一个外部对象,或者通过FactoryBean、@Inject等方式,可能可以注入非容器管理的对象吗?或者,是否可以通过@Autowired的required属性设置为false,允许依赖为null,但这并不改变依赖需要在容器中的要求。 另外,需要考虑Spring的依赖查找(Dependency Lookup)和依赖注入的区别。依赖注入更强调容器主动注入,而查找是对象主动向容器获取。但用户的问题是关于依赖注入的,所以重点在注入过程。 可能的例外情况:如果目标对象在容器中,而依赖对象是通过其他方式提供的,比如使用@Autowired注解一个静态工厂方法创建的对象,或者使用@Resource的lookup属性指定JNDI查找,这时候依赖可能不在Spring容器中,但这种情况属于特殊配置,不是常规的依赖注入场景。 总结:通常情况下,依赖注入的两个对象(目标对象和依赖对象)都需要在IOC容器中,这样容器才能完成依赖的装配。如果目标对象不在容器中(未被Spring管理),则无法进行依赖注入;如果依赖对象不在容器中,Spring无法找到该依赖实例,会导致注入失败(除非有特殊配置,如提供@Bean方法或使用其他外部资源)。 现在需要验证这些思路是否正确。例如,假设目标对象由Spring管理(如用@Component注解),而依赖对象没有被Spring管理(没有注解或未被扫描),那么@Autowired会失败,抛出NoSuchBeanDefinitionException。这说明依赖对象必须在容器中。如果目标对象没有被Spring管理(比如手动new的),那么其依赖不会被注入,因为Spring不知道这个对象的存在。 因此,结论是:在Spring依赖注入中,**目标对象(被注入依赖的对象)必须由IOC容器管理**(即处于容器中),否则容器无法进行注入;而**被注入的依赖对象通常也需要在IOC容器中**,这样容器才能找到并注入它。特殊情况下(如通过工厂方法、JNDI等外部资源),依赖对象可能不在容器中,但这需要额外配置,并非常规场景。 </think>在Spring依赖注入DI)中,**目标对象(被注入依赖的对象)必须由IOC容器管理**(即处于容器中),否则容器无法主动注入依赖;而**被注入的依赖对象通常也需要在IOC容器中**,以便容器能找到并完成注入。但存在特殊场景允许依赖对象不在容器中(需额外配置)。以下是详细分析: ### 一、核心规则:目标对象必须在IOC容器中 依赖注入的本质是**Spring容器主动为对象设置依赖**。若目标对象未被容器管理(如通过`new`手动创建),容器无法感知其存在,自然无法注入依赖。 **示例验证**: ```java // 目标对象(未被容器管理) public class UserService { @Autowired // 不会生效! private UserRepository userRepository; } // 手动创建对象 UserService userService = new UserService(); // userRepository 为 null(未被注入) ``` **结论**:目标对象必须通过`@Component`、`@Service`等注解标记,或通过`@Bean`方法注册到容器中,Spring才会为其注入依赖。 ### 二、依赖对象通常需在IOC容器中 依赖对象(如上述`UserRepository`)通常需要在容器中,否则Spring无法找到匹配的Bean完成注入,会抛出`NoSuchBeanDefinitionException`异常。 **示例验证**: ```java // 目标对象(被容器管理) @Service public class UserService { @Autowired private UserRepository userRepository; // 依赖对象 } // 依赖对象(未被容器管理) public class UserRepository { ... } // 无@Component等注解 // 启动Spring容器时,会报错: // No qualifying bean of type 'UserRepository' available ``` **结论**:依赖对象需通过`@Component`、`@Repository`等注解,或`@Bean`方法注册到容器中,Spring才能注入。 ### 三、特殊场景:依赖对象可不在容器中(需额外配置) 通过以下方式,可让依赖对象不在容器中但仍被注入: #### 1. 工厂方法(FactoryBean) 通过实现`FactoryBean`接口,可自定义依赖对象的创建逻辑。此时依赖对象本身无需在容器中,但`FactoryBean`实例需注册到容器。 **示例**: ```java // 自定义FactoryBean(注册到容器) @Component public class ExternalUserRepositoryFactory implements FactoryBean<UserRepository> { @Override public UserRepository getObject() { // 返回一个不在容器中的UserRepository实例(如外部API客户端) return new UserRepository("外部数据库连接"); } @Override public Class<?> getObjectType() { return UserRepository.class; } } // 目标对象(依赖注入生效) @Service public class UserService { @Autowired private UserRepository userRepository; // 注入FactoryBean创建的实例 } ``` #### 2. JNDI查找(@Resource) 通过`@Resource`的`lookup`属性指定JNDI名称,可从外部资源(如应用服务器的JNDI上下文)获取依赖对象,无需在Spring容器中注册。 **示例**: ```java @Service public class UserService { @Resource(lookup = "java:comp/env/jdbc/ExternalDB") // 从JNDI获取数据源 private DataSource externalDataSource; // 依赖对象不在Spring容器中 } ``` #### 3. @Autowired(required = false) 若依赖对象不存在,设置`@Autowired(required = false)`可避免异常,但此时依赖为`null`(无实际注入效果),仅用于可选依赖场景。 ### 四、总结 - **目标对象必须在容器中**:否则Spring无法感知并注入依赖。 - **依赖对象通常需在容器中**:常规场景下,依赖对象需注册到容器,否则注入失败。 - **特殊场景例外**:通过`FactoryBean`、JNDI等方式,可注入不在容器中的依赖对象(需额外配置)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值