一、什么是DI依赖注入
依赖关系注入 (DI) 是一个过程,通过该过程,对象仅通过构造函数参数、工厂方法的参数或在构造对象实例或从工厂方法返回后在对象实例上设置的属性来定义其依赖关系(即,使
用它们使用的其他对象)。然后,容器在创建 Bean 时注入这些依赖项。这个过程基本上是Bean本身的反函数(因此得名“控制反转”),通过使用类的直接构造或服务定位器模式来控制
其依赖项的实例化或位置。
使用 DI 原则,代码更清晰,当对象与其依赖项一起提供时,解耦更有效。该对象不查找其依赖项,也不知道依赖项的位置或类。
二、依赖注入的方式
依赖注入有三种方式:基于构造函数的依赖关系注入、利用set方法的依赖关系注入、其他的依赖关系注入。
1.基于构造函数的依赖关系注入
这个在Spring(五)的学习中已经是说过了,这里仅再简单叙述一下构造函数注入的方式。
(1)通过index索引进行注入,索引从0开始。
(2)通过传入参数名进行注入,最方便。
(3)通过传参的类型进行注入,不适用于有同类型的情况。
(4)通过bean进行注入。
2.利用set方法的依赖关系注入
通过set方法进行依赖注入是最核心的注入方式。
这个前面的学习也已经用到了,不过前面注入的都是一些简单的基本类型和String类型,这里我们再对一些复杂的类型如List、Map等进行注入方法的学习。
(1)Student和Address是我们要用到的类
Address
package com.jms.pojo;
public class Address {
private int id;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"id=" + id +
", address='" + address + '\'' +
'}';
}
}
Student
package com.jms.pojo;
import java.util.*;
public class Student {
private String name;
private Address address;
private String[] lesson;
private List<String> hobbys;
private Map<String, String> card;
private Set<String> games;
private String graduate;
private Properties info;
public String[] getLesson() {
return lesson;
}
public void setLesson(String[] lesson) {
this.lesson = lesson;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String getGraduate() {
return graduate;
}
public void setGraduate(String graduate) {
this.graduate = graduate;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
@Override
public String toString() {
return "Student{" + "\n" +
"name='" + name + '\'' + "\n" +
"address=" + address.toString() + "\n" +
"lesson=" + Arrays.toString(lesson) + "\n" +
"hobbys=" + hobbys + "\n" +
"card=" + card + "\n" +
"games=" + games + "\n" +
"graduate='" + graduate + '\'' + "\n" +
"info=" + info + "\n" +
'}';
}
}
(2)beans.xml
<bean id="student" class="com.jms.pojo.Student">
<!--普通类型-->
<property name="name" value="jms"/>
<!--Bean-->
<property name="address" ref="address"/>
<!--数组-->
<property name="lesson">
<array>
<value>C</value>
<value>Java</value>
<value>Python</value>
</array>
</property>
<!--List集合-->
<property name="hobbys">
<list>
<value>编程</value>
<value>写作</value>
<value>听音乐</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="学生卡" value="101010101"/>
<entry key="饭卡" value="20202020202"/>
<entry key="水卡" value="30303030303"/>
</map>
</property>
<!--Set-->
<property name="games">
<set>
<value>game1</value>
<value>game2</value>
<value>game3</value>
</set>
</property>
<!--null-->
<property name="graduate">
<null/>
</property>
<!--Properties-->
<property name="info">
<props>
<prop key="学号">100001</prop>
<prop key="姓名">啊范德萨</prop>
<prop key="班级">计算机3班</prop>
</props>
</property>
</bean>
<bean id="address" class="com.jms.pojo.Address">
<property name="id" value="1"/>
<property name="address" value="world"/>
</bean>
(3)测试
@Test
public void studentTest() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Student student = applicationContext.getBean("student", Student.class);
System.out.println(student);
}
测试结果:

3.其他的依赖关系注入
c命名空间注入和p命名空间注入,这是官方给出的拓展的注入方式,p命名空间注入对应set注入,c命名空间注入对应有参构造注入。
使用这两种注入时都需要添加约束,以下是官方给出的使用示例:
p-namespace:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="john-classic" class="com.example.Person">
<property name="name" value="John Doe"/>
<property name="spouse" ref="jane"/>
</bean>
<bean name="john-modern"
class="com.example.Person"
p:name="John Doe"
p:spouse-ref="jane"/>
<bean name="jane" class="com.example.Person">
<property name="name" value="Jane Doe"/>
</bean>
</beans>
c-namespace:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanTwo" class="x.y.ThingTwo"/>
<bean id="beanThree" class="x.y.ThingThree"/>
<!-- traditional declaration with optional argument names -->
<bean id="beanOne" class="x.y.ThingOne">
<constructor-arg name="thingTwo" ref="beanTwo"/>
<constructor-arg name="thingThree" ref="beanThree"/>
<constructor-arg name="email" value="something@somewhere.com"/>
</bean>
<!-- c-namespace declaration with argument names -->
<bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>
</beans>
(本文仅作个人学习记录用,如有纰漏敬请指正)
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem
有什么方法可以告诉sidekiq一项工作依赖于另一项工作,并且在后者完成之前无法开始? 最佳答案 仅使用Sidekiq;答案是否定的。正如DickieBoy所建议的那样,您应该能够在依赖作业完成时将其启动。像这样。#app/workers/hard_worker.rbclassHardWorkerincludeSidekiq::Workerdefperform()puts'Doinghardwork'LazyWorker.perform_async()endend#app/workers/lazy_worker.rbclassLaz
Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject
我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li
目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一