使用注解的方式实现IOC
定义两个实体类
/*** @ClassName Address* @Description TODO* @Author zhongge* @Version 1.0*/
public class Address {public String getLoc() {return loc;}public void setLoc(String loc) {this.loc = loc;}@Overridepublic String toString() {return "Address{" +"loc='" + loc + '\'' +'}';}private String loc;public Address(String loc) {this.loc = loc;}public Address() {}
}/*** @ClassName Student* @Description TODO* @Author zhongge* @Version 1.0*/
public class Student {public Student() {}@Overridepublic String toString() {return "Student{" +"address=" + address +", id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}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;}private Address address;//地址private Integer id;private String name;private Integer age;}
配置xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="com.zhongge.entity.Address"><property name="loc" value="贵州"></property></bean><bean id="student" class="com.zhongge.entity.Student"><property name="address" ref="address"></property><property name="id" value="1001"></property><property name="name" value="李四"></property><property name="age" value="19"></property></bean>
</beans>
测试结果
/*** @ClassName Main* @Description TODO* @Author zhongge* @Version 1.0*/
public class Main {public static void main(String[] args) {//获取IOC容器ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");//从IOC容器中获取对象System.out.println(applicationContext.getBean("address"));System.out.println(applicationContext.getBean("student"));}
}
结果:
补充知识
1️⃣ 构造器注入(不需要无参构造)
如果你想用有参构造直接创建 Student
对象,可以用 <constructor-arg>
标签:
<bean id="address" class="com.zhongge.entity.Address"><property name="loc" value="贵州"/>
</bean><bean id="student" class="com.zhongge.entity.Student"><constructor-arg ref="address"/> <!-- 第一个参数 --><constructor-arg value="1001"/> <!-- 第二个参数 --><constructor-arg value="李四"/> <!-- 第三个参数 --><constructor-arg value="19"/> <!-- 第四个参数 -->
</bean>
特点:
- 直接调用你定义的有参构造方法
- 不需要无参构造
- 参数顺序必须与构造方法一致
2️⃣ Setter 注入(需要无参构造)
这是你现在的写法,Spring 会:
- 调用无参构造创建对象
- 调用
setXxx()
方法注入属性
<bean id="address" class="com.zhongge.entity.Address"><property name="loc" value="贵州"/>
</bean><bean id="student" class="com.zhongge.entity.Student"><property name="address" ref="address"/><property name="id" value="1001"/><property name="name" value="李四"/><property name="age" value="19"/>
</bean>
特点:
- 必须有无参构造
- 属性名要与
setXxx()
方法对应
3️⃣ p 命名空间注入(简化 Setter 注入)
可以用 p:
前缀简化 <property>
写法:
<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="com.zhongge.entity.Address" p:loc="贵州"/><bean id="student" class="com.zhongge.entity.Student"p:address-ref="address"p:id="1001"p:name="李四"p:age="19"/>
</beans>
特点:
- 写法更简洁
- 本质还是 Setter 注入,所以仍需要无参构造
4️⃣ 集合类型注入(可选)
如果你的类中有集合属性,可以这样配置:
<bean id="student" class="com.zhongge.entity.Student"><property name="address" ref="address"/><property name="id" value="1001"/><property name="name" value="李四"/><property name="age" value="19"/><property name="hobbies"><list><value>篮球</value><value>游泳</value></list></property>
</bean>
✅ 总结:
- 构造器注入 →
<constructor-arg>
,不要求无参构造 - Setter 注入 →
<property>
或p:
命名空间,必须有无参构造 - 你的
Student
类有有参构造,如果想用<property>
注入,就必须显式添加无参构造
基于xml的方式的优缺点
- 缺点:基于 XML 的缺点是过于复杂
- 优点:基于 XML 的方式一个类可以创建多个对象