Bean的装配就是Bean依赖注入。Spring容器提供了3中常用的Bean的装配方式,分别是 基于XML的装配 、基于注解的装配 和 自动装配 。
基于XML的装配就是读取XML配置文件中的信息完成依赖注入,Spring容器提供了两种基于XML的装配方式,即属性setter方法注入和构造方法注入
在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter方法来注入属性值。
注意:
实体类User:
@Data
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
}
<bean id="user" class="com.hua.pojo.User">
<property name="id" value="1"/>
<property name="name" value="Nancy"/>
<property name="password" value="11111"/>
bean>
@Test
public void userSetter(){
ApplicationContext ac=new ClassPathXmlApplicationContext("userBean.xml");
User user = ac.getBean("user", User.class);
System.out.println(user);
}
注意:
<bean id="user1" class="com.hua.pojo.User">
<constructor-arg name="id" value="2"/>
<constructor-arg name="name" value="花花"/>
<constructor-arg name="password" value="22222"/>
bean>
@Test
public void userSetter2(){
ApplicationContext ac=new ClassPathXmlApplicationContext("userBean.xml");
User user = ac.getBean("user1", User.class);
System.out.println(user);
}
Spring的常用注解
注解 | 描述 |
---|---|
@Component | 指定一个普通的Bean,可以作用在任何层次 |
@Controller | 指定一个控制器组件Bean,用于控制层的类标识位Spring中的Bean,功能上等同于@Component |
@Service | 指定一个业务逻辑组件Bean,用于将业务逻辑层的类标识为Spring中的Bean,功能上等同于@Component |
@Repository | 指定一个数据库访问组件Bean,用于将数据访问层的类标识为Spring中的Bean,功能上等同于@Component |
@Scope | 指定Bean实例的作用域 |
@Value | 指定Bean实例的注入值 |
@AutoWired | 指定要自动装配的对象 |
@Resource | 指定要注入的对象 |
@Qualifier | 指定要自动装配的对象名称,通常与@Autowired联合使用 |
@PostConstruct | 指定Bean实例完成初始化后调用的方法 |
@PreDestroy | 指定Bean实例销毁前调用的方法 |
注意:虽然**@Controller**、@Service、@Repository注解的功能与**@Component注解的功能相同,但是为了使被标注的类本身的用途更加清晰,建议在实际开发中使用@Controller**、@Service和**@Repository**注解分别对控制组件Bean、业务逻辑组件Bean和数据访问组件Bean进行标注。
1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。
3、@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。
一般@Autowired和@Qualifier一起用,@Resource单独用。当然没有冲突的话@Autowired也可以单独用。
案例:
实体层UserDao
@Data
@AllArgsConstructor
@NoArgsConstructor//必须要加无参构造
@Component//将User类注册为Spring容器中的Bean
@Scope("singleton")//单例模式
public class User {
@Value("1")
private int id;
@Value("张三")
private String name;
@Value("33333")
private String password;
}
数据访问层UserDao接口以及UserDaoImpl接口实现类
public interface UserDao {
public void save();
}
//使用@Repository注解将UserDaoImpl类标识为Spring中的Bean
@Repository
public class UserDaoImpl implements UserDao{
@Override
public void save() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean("user", User.class);
System.out.println(user);
System.out.println("执行UserDaoImpl.save()");
}
}
业务逻辑层UserService接口以及UserServiceImpl接口实现类
public interface UserService {
public void save();
}
//使用@Service注解将UserServiceImpl类标识为String中的Bean
@Service
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
public void save() {
this.userDao.save();
System.out.println("执行了UserServiceImpl.save");
}
}
控制层UserController
//使用Controller注解将UserController类标识为Spring中的Bean
@Controller
public class UserController {
//使用@Resource注解注入UserService
@Resource
private UserService userService;
public void save(){
this.userService.save();
System.out.println("执行了UserController.save()");
}
}
xml配置
<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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.hua"/>
beans>
测试类
@Test
public void annotationTest(){
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
UserController userController = ac.getBean("userController", UserController.class);
userController.save();
}