Q:Spring中有几种注入方式?他们之间有什么区别?能否说下其原理?
带着问题找解决方案:
首先Spring中有三种常用的注入方式,分别是:
1.设值注入(setXX注入常用)
2.构造器注入(constructor-arg,死了的应用)
3.注解注入(@....)
4.接口注入(不推荐)
一、我们先来说说第一种set注入。
提示:不需要get方法可以不用生成。参数比较多的话,一起生成也没关系。
1):model:
package com.cn.Singit.Student;
public class Student {
String name ;
String sex;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
2):xml:
<bean id="Student" class="com.cn.Singit.Student">
<property name="id" value="1"></property>
<property name="name" value="student"></property>
<property name="sex" value="男"></property>
<property name="age" value="18"></property>
</bean>
3):Test
public class Test{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
二、构造函数注入
构造器注入依赖于构造方法的实现,----------构造方法可以是有参数的,也可以是无参数的 。
在没有spring之前,我们在大多数情况下,我们都是通过构造方法来创建类对象,
Spring可以采用反射的方式,通过构造方法来完成注入,这就是构造方法的原理。
1.引入spring的支持
2.通过描述具体的类,构造方法和其中的参数,这样spring就可以通过相应的信息用反射的方式创建对象。
3.在test文件中加载spring配置文件的方法
String configLocation ="applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
在spring中一切的资源都是靠bean来注入的。
1):model
package com.cn.Singit.Student;
public class Student {
String name ;
String sex;
int age;
public Student(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
2):XML
<bean id="student" class="com.cn.Singit.Student">
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="小明"/>
<constructor-arg name="sex" value="男"/>
<constructor-arg name="age" value="18"/>
</bean>
说明:<constructor-arg name="id" value="1"/>也可以改成<constructor-arg index="0" value="1"/>方式;boolean的值既可以用0/1填充,也可以用true/false填充
注意:构造器注入和setter注入都是通过java的反射技术得以实现的。
首先将构造方法设置为无参的构造方法,然后利用setter注入为其设置新的值,
这也是通过java的反射技术得以实现的
三、注解注入:(用的最多)
在介绍注解注入的方式前,先简单了解bean的一个属性autowire,autowire主要有三个属性值:constructor,byName,byType。
constructor:通过构造方法进行自动注入,spring会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入到多参数的构造方法中。
byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。
byType:查找所有的set方法,将符合符合参数类型的bean注入。
下面进入正题:注解方式注册bean,注入依赖
主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:
@Component:可以用于注册所有bean
@Repository:主要用于注册dao层的bean
@Controller:主要用于注册控制层的bean
@Service:主要用于注册服务层的bean
描述依赖关系主要有两种:
@Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。
@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;
public UserService(){
@Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找,
@Autowired
@Qualifier("userDaoJdbc")
private IUserDao userDao;
写在最后:虽然有这么多的注入方式,但是实际上开发的时候自己编写的类一般用注解的方式注册类,用@Autowired描述依赖进行注入,一般实现类也只有一种(jdbc or hibernate or mybatis),除非项目有大的变动,所以@Qualifier标签用的也较少;但是在使用其他组件的API的时候用的是通过xml配置文件来注册类,描述依赖,因为你不能去改人家源码嘛。
注意:注入过程中必须保证名称的一致。不然会报 UnsatisfiedDencyException异常。
四、接口注入
有时候资源并非来自于自身的系统,而是来自于外界,
比如说数据库连接资源完全可以在Tomcat下配置,
然后通过JNDI的方式去获取它,这样的数据库连接资源就属于开发工程外的资源。
Spring中property和ied-arg区别
Spring三种常用的注入方式比较(优缺点):
接口注入:接口注入模式因为具备侵略性,要求组建必须与特定的接口相关联,所以并不被看好,实际应用有限。
Setter注入:Setter注入更为直观,如果依赖关系较为复杂,构造子注入模式的构造函数也会相当庞大,此时Setter注入就显得更为简洁、如果用到了第三方类库,要求我们提供一个默认的构造函数,此时构造子模式就不大适用了。
构造器注入:在构造期间完成一个完成的合法的对象。所有依赖关系在构造函数中集中呈现。依赖关系在构造器时由容器一次性设定,组建被创建后一直处于相对不变在稳定状态。只有组建的创建者关心其内部的依赖关系,对调用者而言,改依赖关系处于“黑盒”之中。
总结
为什么需要使用注入方式?一句话归结:
理论上:构造函数注入原则上java使用更符合更合理,Setter注入作为补充。
实际上:setter注入可以取得更加直观的效果,在工作上有不可比拟在优势,所以Setter注入依赖关系应用更加广泛。
本文详细介绍了Spring中的四种注入方式:set注入、构造器注入、注解注入和接口注入。set注入通过setter方法完成,构造器注入依赖构造方法,注解注入常用且灵活,而接口注入则较少使用。文中还探讨了各种注入方式的原理、区别和应用场景,并提到了Spring中的autowire属性和@Resource、@Autowired注解的使用。
173万+





