一.Bean的自动装配
1.测试环境的搭建
(1)pojo中有三个实体类
Cat类
package com.yl.pojo;
public class Cat {
public void shout(){
System.out.println("喵喵~~~");
}
}
Dog类
package com.yl.pojo;
public class Dog {
public void shout(){
System.out.println("旺旺~~");
}
}
People类
package com.yl.pojo;
public class People {
private String name;
private Cat cat;
private Dog dog;
public People() {
}
public People(String name, Cat cat, Dog dog) {
this.name = name;
this.cat = cat;
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", cat=" + cat +
", dog=" + dog +
'}';
}
}
(2)resources中的配置文件beans.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/>
<bean id="dog" class="com.yl.pojo.Dog"></bean>
<bean id="cat" class="com.yl.pojo.Cat"></bean>
<!--以前的写法-->
<bean id="people" class="com.yl.pojo.People">
<property name="name" value="人" />
<property name="dog" ref="dog" />
<property name="cat" ref="cat" />
</bean>
</beans>
2.简介
- 自动装配是Spring满足bean依赖一种方式!
- Spring会在上下文中自动寻找,并自动给bean装配属性!
在Spring中有三种装配的方式
- (1)在xml中显示的配置
- (2)在java中显示配置
- (3)隐式的自动装配bean
3.ByName自动装配
byName: 会自动在容器上下文中查找和自己对象set方法后面的值对应的 bean id,然后自动装配,就不用去写类似于< property name=“dog” ref=“dog” />的代码了
注意:使用时需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
<!--byName自动装配后的写法-->
<bean id="people" class="com.yl.pojo.People" autowire="byName">
<property name="name" value="人" />
</bean>
4.ByType自动装配
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean,因此不需要id,只需要class类型相同即可
注意:需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
<bean class="com.kuang.pojo.Cat"/>
<bean class="com.kuang.pojo.Dog"/>
<bean id="people" class="com.yl.pojo.People" autowire="byType">
<property name="name" value="人" />
</bean>
5.使用注解实现自动装配
首先要导入约束并配置注解支持
容易忘记的注解支持:< context:annotation-config/>
<?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>
(1)@Autowired
直接在属性上使用即可
@Autowired
private Cat cat;
好处:
使用Autowired 我们可以不用编写Set方法了,前提是你这个自动装配的属性在 IOC(Spring)容器中存在,且符合名字byname!
拓展----@Nullable
字段标记了这个注解,说明这个字段可以为null;
以下代码name可以为空,不会报空指针异常的错误
public People(@Nullable String name) {
this.name = name;
}
在Autowired注解中设定
public class People {
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
(2)@Qualifier
如果装配对象过多,自动装配无法通过一个注解@Autowired完成的时候自动装配无法通过一个注解@Autowired完成的时候,就可以使用@Qualifier(value=“xxx”)去配置
<bean id="dog" class="com.yl.pojo.Dog"></bean>
<bean id="dog2" class="com.yl.pojo.Dog"></bean>
<bean id="cat" class="com.yl.pojo.Cat"></bean>
<bean id="cat2" class="com.yl.pojo.Cat"></bean>
@Qualifier(value="cat2")
private Cat cat;
@Resource(name = "dog2")
private Dog dog;
(3)@Resource注解
既可以通过id查找,也可以通过类型查找,集合了ByName与ByType
@Resource(name = "cat2")
private Cat cat;
@Resource
private Dog dog;
@Resource 和@ Autowired 的区别:
- (1)都是用来自动装配的,都可以放在属性字段上
- (2)实现方式的不同:
@ Autowired 通过byType的方式实现,而且必须要求这个对象存在!
@ Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!
- (3)执行顺序不同:
@ Autowired 通过byType的方式实现。
@ Resource 默认通过byname的方式实现。
二.使用注解开发
1.导入context约束,增加注解的支持
在resources包下建立beans.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"
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:component-scan base-package="com.yl.pojo" />
<!--注解驱动的支持-->
<context:annotation-config/>
</beans>
2.注解的使用
pojo中的User类
@Component//相当于组件
//等价于<bean id="user" class="com.yl.pojo.User" />
public class User {
public String name;
//相当于 <property name="name" value="张三"/>
@Value("张三")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
编写测试类
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) context.getBean("user");
System.out.println(user.toString());
}
3.衍生的注解
@Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
-
dao 【@Repository】
-
service 【@Service】
-
controller 【@Controller】
这四个注解功能与@Component都是一样的,都是代表将某个类注册到Spring中,装配Bean
4.作用域(@Scope)
prototype:原型模式
singleton:单例模式
@Component
@Scope("prototype")
public class User {
public String name;
@Value("张三")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
5.xml与注解
(1)xml 与 注解的适用范围:
- xml 更加万能,适用于任何场合!维护简单方便
- 注解不是自己类使用不了,维护相对复杂!
(2)xml 与 注解最佳实践:
- xml 用来管理bean;
- 注解只负责完成属性的注入;
9、使用Java的方式配置Spring
(1)在pojo包下创建实体类
//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("张三")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
(2)在config包下创建java配置文件
package com.yl.config;
import com.yl.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
@Configuration
@ComponentScan("com.yl.pojo")
@Import(ylConfig2.class)
public class ylConfig {
//@Bean相当于注册一个bean标签
//这个方法的名字,就相当于bean标签中的id属性
//这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User getUser(){
return new User();
}
}
(3)编写测试类
package ceshi;
import com.yl.config.ylConfig;
import com.yl.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Ceshi1 {
public static void main(String[] args) {
//如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的class对象加载!
ApplicationContext context = new AnnotationConfigApplicationContext(ylConfig.class);
User getUser = (User) context.getBean("getUser");
System.out.println(getUser);
}
}