1. 类注解、方法注解
告诉spring管理bean—>bean的存储
1、类注解:五大注解
@Controller(控制器存储)、
@Service(服务存储)、
@Repository(仓库存储)、
@Component(组件存储)、
@Configuration(配置存储)
2、方法注解:@Bean,
@Bean必须和类注解一起使用
2. 类注解、方法注解Bean名称命名规则
2.1. 五大类注解
a、默认类名首字母小写,如果前两位字母均为大写,则为原类名
b、也可以指定Bean的名称,指定方法例如:@Controller(“beanName”)
2.2 方法注解@Bean
默认名称:方法名
也可以指定名称:@Bean(“beanName”)、
@Bean({"u1","user1"})一个bean(对象)有两个名称
3. 启动类中获取bean的方式
3.1 由BeanFactory提供
ApplicationContext 继承了
BeanFactory,
ApplicationContext的功能比
BeanFactory方法更多,更强大
扫描路径
spring默认扫描路径:是启动类所在路径
使用
@ComponentScan("包路径/类所在路径")就可以指定spring扫描路径
3.2 根据类型来获取bean
被spring管理的对象统称为bean:即bean指对象
3.3 根据名字来获取bean
spring帮我们创建对象,会给对象起名字
如果未命名:spring会指定名称,类名首字母小写,小驼峰
未命名:如果类名前两位字母都是大写,Bean的名称为原始类名
为类添加注解后,未命名的类,spring会指定名字
获取bean名字为userService的类
(2)命名:注解(“名字”)
@Controller(“名字”)
4. IoC详细用法
4.1 五大注解
为什么要这么多类注解?当看到类注解之后,就能直接了解当前类的用途.
• @Controller:控制层,接收请求,对请求进⾏处理,并进行响应。除了具备让spring管理的功能外,还具备路由功能,接口入口必须要有@controller
• @Servie:业务逻辑层,处理具体的业务逻辑.
• @Repository:数据访问层,也称为持久层.负责数据访问操作
• @Configuration:配置层.处理项⽬中的⼀些配置信息
(1)@Controller(控制器存储)
(2)@Service(服务存储)
(3)@Repository(仓库存储)、
(4)@Component(组件存储)、
(5)@Configuration(配置存储)
4.2 方法注解@Bean
@Bean需要搭配五大注解使用,因为只有类被注解时,spring才会去扫描被注解的类
@Bean注解默认名字为原方法名
5. DI注入依赖
Ioc:存储对象,并对对象进行管理
DI:使用对象,将对象取出来使用
5.1 AutoWired属性注入
@Autowired
private UserService userService;
优点:
简洁,使⽤⽅便;
缺点:
▪ 只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指 针异常)
▪ 不能注⼊⼀个Final修饰的属性
5.2 构造方法注入
public class UserController {
private PeoService peoService;
private UserService userService;
public UserController() {
}
//此时只有该构造方法被初始化,userService对象被注入
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
public UserController(UserService userService,PeoService peoService) {
this.userService = userService;
this.peoService = peoService;
}
构造方法注入时,如果有多个构造函数,spring只能默认识别第一个构造方法。我们可以使用
@Autowired注解来帮助spring选择使用哪一个构造方法来注入对象
构造方法注入优点:
▪
可以注入final修饰的属性
属性被final修饰时需要先被初始化
▪
注入的对象不会被修改
▪
依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法.
▪
通用性好,构造方法是JDK支持的,所以更换任何框架,他都是适用的
5.3 set方法注入
@Controller
public class UserController3 {
//注⼊⽅法3: Setter⽅法注⼊
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public void sayHi(){
System.out.println("hi,UserController3...");
userService.sayHi();
}
}
6. @Autowired存在问题
Autowired先根据名称获取对象,如果没有获取到就根据对象的类型来匹配
//创建两个对象
@Component
public class Autowired {
@Bean("u1")
public User user1(){
User user = new User();
user.setName("zhangsan");
user.setAge(18);
return user;
}
@Bean
public User user2() {
User user = new User();
user.setName("lisi");
user.setAge(19);
return user;
}
}
//获取Bean(对象)
@Controller
public class UserController {
@Autowired
private UserService userService;
//注⼊user
@Autowired
private User user;//此时这里会报错, @Autowired注解先根据bean名称来注入(获取)对象的,找不到的话就会根据类型来获取对象
//而这里User对象有两个,就不知道注入哪个对象所以会出现错误
public void sayHi(){
userService.sayHi();
System.out.println(user);
}
如何解决上面的问题?
•
@Primary
•
@Qualifier
•
@Resource
@Primary:
使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现
@Component
public class BeanConfig {
@Primary //指定该bean为默认bean的实现
@Bean("u1")
public User user1(){
User user = new User();
user.setName("zhangsan");
user.setAge(18); return user; }
@Bean
public User user2() {
User user = new User();
user.setName("lisi");
user.setAge(19);
return user;
}
}
@Qualifier:
使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean 的名称。
@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
@Controller
public class UserController {
@Qualifier("user2")
//指定bean名称
@Autowired
private User user;
public void sayHi(){
System.out.println("hi,UserController...");
System.out.println(user);
}
}
使⽤@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称
@Controller
public class UserController {
@Resource(name = "user2")
private User user;
public void sayHi(){
System.out.println("hi,UserController...");
System.out.println(user);
}
}
常见面试题: @Autowird与@Resource的区别
•
@Autowired是spring框架提供的注解,⽽@Resource是JDK提供的注解
•
@Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired来说, @Resource⽀持更多的参数设置,例如name设置,根据名称获取Bean。