为主配置文件引入新的命名空间(约束)
context
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
beans>
开启使用注解代理配置文件
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.jjs.bean">context:component-scan>
beans>
在类中使用注解,完成配置
使用@component将User类配置到Spring容器中
package cn.jjs.bean;
import org.springframework.stereotype.Component;
@Component("user")
public class User {
private String name;
private Integer age;
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
}
其中@component(“user”)相当于XML中的
测试类:
package cn.jjs.a_annocation;
import cn.jjs.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User u = (User)ac.getBean("user");
System.out.println(u);
}
}
结果:
User{name='null', age=null, car=null}
@Scope(scopeName = "prototype|singleton")
默认为singleton,单例
prototype,多例
@Component("user")
public class User {
@Value("Tom")
private String name;
private Integer age;
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
}
@Value可以加在name属性上,也可以加在setName()方法上。
在name成员变量上,通过反射的Field赋值(破坏了对象的封装性),
在setName()方法上,通过set方法赋值。
自动装配,用于引用类型
User.java
package cn.jjs.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("user")
public class User {
@Value("Tom")
private String name;
private Integer age;
@Autowired
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
}
Car.java
package cn.jjs.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("car")
public class Car {
private String name;
private String color;
public String getName() {
return name;
}
@Value("Honda")
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
@Value("Red")
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
结果:
User{name='Tom', age=null, car=Car{name='Honda', color='Red'}}
问题:如果匹配多个类型一致的对象,将无法选择具体注入哪个对象。
比如在applicationContext.xml中再配置一个Car
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.jjs.bean">context:component-scan>
<bean name="car2" class="cn.jjs.bean.Car">
<property name="name" value="WV">property>
<property name="color" value="black">property>
bean>
beans>
使用@Qualifier(“car2”)注解告诉Spring容器自动装配哪个对象,与@Autowired成对使用。
package cn.jjs.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("user")
public class User {
@Value("Tom")
private String name;
private Integer age;
@Autowired
@Qualifier("car2")
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
结果:
User{name='Tom', age=null, car=Car{name='WV', color='black'}}
@Autowired与@Qualifier(“car2”)成对使用太啰嗦,使用@Resource(name = “car2”)可以替代。
手动注入,指定注入哪个名称的对象。
package cn.jjs.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component("user")
public class User {
@Value("Tom")
private String name;
private Integer age;
@Resource(name = "car2")
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
在User.java中,
@PostConstruct
public void init() {
System.out.println("init()");
}
注明,在对象创建后立即调用。
相当于XML中的:init-method
在User.java中,
@PreDestroy
public void destroy() {
System.out.println("destroy");
}
注明,在对象销毁前调用。
相当于XML中的:destroy-method