IOC容器
IOC容器
依赖注入
实体类:
public class User {
private int id;
private String name;
private String password;
//get set 构造函数省略
}
方式一:基于构造函数的依赖注入
-
构造函数参数类型匹配
<bean id="user" class="cn.gbl.pojo.User"> <constructor-arg type="int" value="1"/> <constructor-arg type="java.lang.String" value="xxgbl"/> <constructor-arg type="java.lang.String" value="1234"/> </bean>测试:
public void Hello(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = context.getBean("user", User.class); System.out.println(user); } //结果 User{id=1, name='xxgbl', password='1234'} -
构造函数参数索引
<bean id="user1" class="cn.gbl.pojo.User"> <constructor-arg index="0" value="2"/> <constructor-arg index="1" value="gbl"/> <constructor-arg index="2" value="4321"/> </bean>测试:
@Test public void Hello(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 = context.getBean("user1", User.class); System.out.println(user1); } //结果 User{id=2, name='gbl', password='4321'} -
构造函数参数名称
<bean id="user2" class="cn.gbl.pojo.User"> <constructor-arg name="id" value="3"/> <constructor-arg name="name" value="xxxx"/> <constructor-arg name="password" value="3333"/> </bean>测试:
@Test public void Hello(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user2 = context.getBean("user2", User.class); System.out.println(user2); } //结果 User{id=3, name='xxxx', password='3333'}
方式二:基于Setter的依赖注入(重点)
实体类:
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Set<String> games;
private Map<String,String> card;
private Properties info;
//get set 构造函数省略
}
public class Address {
private String country;
private String city;
//get set 构造函数省略
}
set注入:
<bean id="student" class="cn.gbl.pojo.Student">
<!-- -->
<property name="name" value="张三"/>
<!--bean注入 -->
<property name="address" ref="address"/>
<!--数组注入 -->
<property name="books">
<array>
<value>Java</value>
<value>SSM</value>
<value>vue</value>
</array>
</property>
<!--list注入 -->
<property name="hobbies">
<list>
<value>吃</value>
<value>喝</value>
<value>玩</value>
<value>乐</value>
</list>
</property>
<!--set注入 -->
<property name="games">
<set>
<value>lol</value>
<value>cs</value>
<value>yys</value>
</set>
</property>
<!--map注入 -->
<property name="card">
<map>
<entry key="身份证" value="111111"/>
<entry key="银行卡" value="222222"/>
</map>
</property>
<!--properties注入 -->
<property name="info">
<props>
<prop key="user">xxgbl</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean>
<bean id="address" class="cn.gbl.pojo.Address">
<property name="city" value="上海"/>
<property name="country" value="中国"/>
</bean>
测试:
@Test
public void Hello(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = context.getBean("student", Student.class);
System.out.println(student);
}
//结果
Student{
name='张三',
address=Address{country='中国', city='上海'},
books=[Java, SSM, vue],
hobbies=[吃, 喝, 玩, 乐],
games=[lol, cs, yys],
card={身份证=111111, 银行卡=222222},
info={password=1234, user=xxgbl}
}
拓展:也可以使用p:namespace和c:namespace注入(看官方文档,在此不多做赘述)
自动装配
上述实现依赖注入的方式都是手动进行注入的,spring提供了自动装配机制。
实体类:
public class Cat {
private String name;
//get set 构造函数省略
}
public class Dog {
private String name;
//get set 构造函数省略
}
public class People {
private Cat cat;
private Dog dog;
private String name;
//get set 构造函数省略
}
方式一:基于xml的自动装配
-
byName
<bean id="cat" class="cn.gbl.pojo.Cat"> <property name="name" value="Jack"/> </bean> <bean id="dog" class="cn.gbl.pojo.Dog"> <property name="name" value="Tony"/> </bean> <bean id="people" class="cn.gbl.pojo.People" autowire="byName"> <property name="name" value="xxgbl"/> </bean>测试:
@Test public void people(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = context.getBean("people", People.class); System.out.println(people); } //结果 People{name=xxgbl, cat=Cat{name='Jack'}, dog='Dog{name='Tony'}'} -
byType
<bean id="cat" class="cn.gbl.pojo.Cat"> <property name="name" value="Jack"/> </bean> <bean id="dog" class="cn.gbl.pojo.Dog"> <property name="name" value="Tony"/> </bean> <bean id="people" class="cn.gbl.pojo.People" autowire="byType"> <property name="name" value="xxgbl"/> </bean>
注意:
- 使用byName时,必须保证bean的id是唯一的。
- 使用byType时,必须保证bean的class是唯一的。
方式二:基于注解的自动装配
-
@Autowired
在配置文件中加入注解支持:
<?xml version="1.0" encoding="UTF-8"?> <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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <beans> <bean id="cat" class="cn.gbl.pojo.Cat"> <property name="name" value="Jack"/> </bean> <bean id="dog" class="cn.gbl.pojo.Dog"> <property name="name" value="Tony"/> </bean> <bean id="people" class="cn.gbl.pojo.People"> <property name="name" value="xxgbl"/> </bean> </beans> </beans>在实体类中添加注解:
public class People { private String name; @Autowired private Cat cat; @Autowired private Dog dog; }测试:
@Test public void people(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = context.getBean("people", People.class); System.out.println(people); } //结果 People{name=xxgbl, cat=Cat{name='Jack'}, dog='Dog{name='Tony'}'}@Autowired有一个required 属性默认为true,将@Autowired(required = false)设为flase,字段可以为空。
-
@Resource
public class People { @Resource private Cat cat; @Resource private Dog dog; private String name; }
注意:
@Autowired通过byType的方式实现。
@Resource通过byName的方式实现,如果找不到名字,就会去找类型。
使用注解开发
在spring配置文件中增加注解支持:
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描 cn.gbl 下的注解,此包下的注解生效 -->
<context:component-scan base-package="cn.gbl"/>
<context:annotation-config/>
</beans>
在类中添加注解:
@Component //等价于<bean id="user" class="cn.gbl.pojo.User"/>相当于在配置文件中注入了一个bean
public class User {
@Value("xxgbl")
private String name;
//get set 构造函数省略
}
-
注册bean
-
pojo:实体类中用@Component。
-
dao:dao层用@Repository。
-
service:service层用@Service。
-
controller:controller层用@Controller。
它们作用都是一样的,都是向配置文件中注册bean,只不过是每一层的名字不一样。
-
-
属性注入
@Value(""):使用@Value("")注入属性值。
-
bean作用域:
@Scope():使用@Scope():修改bean的作用域。
使用Java代码配置Spring
实体类:
@Component
public class User {
@Value("xxgbl")
private String name;
}
配置类:相当于配置文件
@Configuration
public class UserConfig {
@Bean //相当于将User类注入到配置文件,方法名就是bean的名字,相当于id
public User getUser(){
return new User();
}
}
测试:
@Test
public void people(){
ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
User user = context.getBean("getUser",User.class);
System.out.println(user);
}
//结果
User{name='xxgbl'}

浙公网安备 33010602011771号