Spring注入依赖(DI),可以在配置文件(applicationContext)中配置,也可以通过注解在类中配置。对于Spring不太了解的请看我上一篇文章!
一、Spring在配置文件中的四种注入方式
上一篇总结的知识点关于bean元素的,这里不再重复
1、set方式注入(重点)
set方式注入值类型:
(这里只是测试一下,所以没有用到主配置文件,仅仅只是在包里面)
<!-- set方式注入值类型 -->
<bean name="user" class="com.zl.bean.User">
<!-- 为User对象中名为name的属性注入tom作为值 -->
<property name="name" value="Amy"></property>
<property name="age" value="16"></property>
<property name="sex" value="男"></property>
</bean>
重写一下User类toString方法:
写一个方法测试一下:
打印结果:
set方式注入引用类型:
先写一个Car类,让Car有name和color属性,并为两个属性添加set和get方法,重写toString方法,然后让User类拥有Car属性及其set、get方法,重写toString方法!applicationContext.xml配置文件:
测试方法可以不用改,最后打印结果:
2、构造方法注入
3、p名称空间注入(了解即可)
<!-- p名称空间注入 ,还是走的set方法,只是简化了property的写法
先导入p名称空间xmlns:p="http://www.springframework.org/schema/p"
再使用p:属性完成注入:
值类型:p:属性名="值" 对象类型:p:属性名-ref="bean名称"
-->
<bean name="user3" class="com.zl.bean.User" p:name="Jack" p:age="25" p:car-ref="car"></bean>
4、spel注入(了解即可)
<!-- spel(Spring Expression Language)注入
取其他对象的属性值,且只能取基本类型的,下面这个是取的user对象的名字赋给user4的name -->
<bean name="user4" class="com.zl.bean.User">
<property name="name" value="#{user.name}"></property>
<property name="car" value="car"></property>
</bean>
补充:复杂类型注入:
<!-- 复杂类型 -->
<bean name="collectionBean" class="com.zl.injection.CollectionBean">
<!-- 如果数组/List只有一个值/对象 ,直接使用value/ref即可-->
<!-- <property name="arr" value="Tom"></property> -->
<!-- array多个元素注入 -->
<property name="arr">
<array>
<value>Tom</value>
<value>Jerry</value>
<ref bean="user2"/>
</array>
</property>
<!-- List类型多个值/对象注入 -->
<property name="list">
<list>
<value>Mary</value>
<value>July</value>
<ref bean="user3"/>
</list>
</property>
<!-- Map类型一个或多个值/对象注入 -->
<property name="map">
<map>
<entry key="url" value="www.baidu.com"></entry>
<entry key="user" value-ref="user4"></entry>
<entry key-ref="user3" value-ref="user4"></entry>
</map>
</property>
<!-- Property类型一个或多个值/对象注入 -->
<property name="property">
<props>
<prop key="driver">com.jdbc.mysql.Driver</prop>
<prop key="username">Andy</prop>
</props>
</property>
</bean>
二、注解配置Spring的步骤
1、为主配置文件引入新的命名空间(约束) spring-context
在Spring的四个核心包和两个日志包的基础上,在使用注解时,还需要导入aop包:
添加约束 步骤如下:
context.xsd的路径可以参考下面:
配置applicationContext.xml,下面是在source视图,在上一篇博客添加了beans的命名空间基础上,添加context的命名空间,下面切换到Design视图:
2、开启使用注解代替配置文件
3、在类中使用注解
创建一个User类,不添加构造方法:
package com.zl.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("user")
//相当于在配置文件里的<bean name="user" class="com.zl.bean"></bean>
//后来又衍生出了Service层的@Service、Web层的@Controller、DAO层的@Repository 注解
//@Scope(scopeName="prototype") //修改对象的作用范围,这里改成了原型 (prototype),默认为单例(singleton)
public class User {
/**
* @Value("tom")给name赋值为tom,
* 1.可以加在成员变量前面(通过反射的Field赋值,破坏了对象的封装性),
* 2.也可以加在setName方法前面(通过set方法赋值,更优)
*/
@Value("tom")
private String name;
@Value("18")
private Integer age;
private String sex;
/**
* 1. @Autowired 自动装配,根据类型在容器中检测,所以Car类在定义时要在前面加@Component
* 当匹配到多个类型一致的对象,将无法选择具体注入哪一个对象,这时,可以使用
* 2. @Qualifier注解告诉Spring容器自动装配到那个名称的对象。例如:@Qualifier("car2")
* 有多个注解时,上述两个注解太麻烦了,可以用@Resource(name="car2")直接指定了对象的名称
*/
@Autowired
private Car car;
@PostConstruct //在对象被创建后被调用,init-method
public void init() {
System.out.println("初始化对象");
}
@PreDestroy //在对象销毁之前被调用,destroy-method
public void destroy() {
System.out.println("销毁对象");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", sex=" + sex + ", car=" + car + "]";
}
}
Car类:
package com.zl.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("car")
public class Car {
@Value("宝马")
private String name;
@Value("屎黄色")
private String color;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car [name=" + name + ", color=" + color + "]";
}
}
写一个测试的方法:
@Test
public void test() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User)ac.getBean("user");
System.out.println(user);
ac.close();//close方法时ClassPathXml的,ApplicationContext没有。这里是为了能够看到destroy方法调用了
}
打印结果:
补充:上一篇测试时,是在main方法中调用的,上例中使用JUnit4测试的
用eclipse的可以参考一下,在需要用到Junit4的项目名上单击右键,选择Build Path