目录
类注解
BeanName生成
方法注解
方法注解重命名
获取Bean对象
注入方式
属性注入
构造方法注入
setter方法注入
三种注入的区别
Resource注解
同一个类型被注入多次
Spring的注解可以帮助我们更方便的放入和取出对象
创建maven项目
1、pom.xml引入Spring框架的依赖
2、配置Spring信息
其中:
五大注解
@Controller 控制器存储 @Service 服务存储 @Repository 仓库存储 @Component 组件存储 @Configuration 配置存储
@Controller
public class Spring {
public void print() {
System.out.println("spring");
}
}
public class use {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//这里 我们并没有指定id,默认小驼峰
Spring spring=context.getBean("spring",Spring.class);
spring.print();
}
}
加了@controller注解后,Spring类注册到了框架内
其他四个注解也可以起到注册作用
这五个注解起到了同一个作用,都是将类注册到Spring框架中,那为啥要有5个呢
在一个完整的体系中,一个程序至少分为5层:
1、controller层为控制层,主要处理外部请求,也就是校验前端数据(前端请求数据是否合理)
2、service层为业务层,用来实现业务逻辑(数据组装和接口调用)
3、Repository层为数据持久层(Dao层),用于操作数据库
4、Component层为组件层
5、Configuration层为配置层
使用五种注解,我们可以通过注解明白这个类处于哪一层,执行的是什么功能、增加代码的可读性
这5大类注解的关系:
查看源码,发现Component接口是其他四个注解接口的父接口,其他四个注解之间是“兄弟”关系
public class use {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//这里 我们并没有指定id,默认小驼峰
Spring spring=context.getBean("spring",Spring.class);
spring.print();
API api=context.getBean("aPI",API.class);
api.print();
}
}
我们之前说BeanName默认小驼峰 但是当类名是API这种时,使用小驼峰不能获取到对象 我们去研究AnnotationBeanNameGenerator类的源码(注解BeanName的生成)
这个最终生成BeanName执行的方法,我们会发现这个方法是java类的方法,也就是说,最终生成BeanName的方法是由JDK提供的
调用这个方法,来检查这个结论:
也就说,API类的BeanName是API
@Bean:添加到方法上
Bean注解不可以直接加在类上
方法注解是要加在方法上的,用来将返回的对象注册进Spring,也就是说这个方法,要返回一个Bean对象
public class BeanMethod {
//加了Bean注解后,这个方法返回的User对象 将会被注册进入Spring
@Bean
public User init() {
User user = new User();
user.setName("zhangsan");
return user;
}
}
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
使用方法注解,BeanName默认是方法名
这时发现报错了,有两种可能性:1、User对象没注册进入Spring2、BeanName不正确
这个User对象只会注册一次,我们可以使用User user=context.getBean(User.class),来排查是什么原因,这时也发生了报错
也就说,User对象并未注册进入Spring框架
只使用一个Bean注解是无法将对象存储进入框架,必须搭配一个五大类注解
@Service
public class BeanMethod {
//加了Bean注解后,这个方法返回的User对象 将会被注册进入Spring
@Bean
public User init() {
User user = new User();
user.setName("zhangsan");
return user;
}
}
使用方法注解,BeanName默认使用方法名,可以利用方法注解的name属性起别名
不使用name属性时,BeanName默认方法名,使用name属性之后,BeanName只可以是name属性内的名称
对象装配:将对象取出来放到某一个类中,也称为对象注入
对象装配的实现方式有三种:
1、属性注入 (使用@Autowired注解)
2、构造方法注入
3、Setter注入
@Controller
public class UserApplication {
@Autowired
private User user;
public void print() {
System.out.println("user -》" + user);
}
}
@Autowired
private User user;
这个代码的意思是,告诉Spring,在加载 UserApplication类时,要先将User对象注入到user这个属性中,也就是要先得到User对象
@Controller
public class UserController {
private User user;
@Autowired
public UserController(User user) {
this.user = user;
}
public void print() {
System.out.println(user.getName());
}
}
在调用UserController类时,执行构造方法,构造方法执行时,@Autowired注解告诉Spring,要先将User对象注入到user这个属性中,也就是要先得到User对象
@Controller
public class UserController {
private User user;
@Autowired
public void setUser(User user) {
this.user = user;
}
public void print() {
System.out.println(user.getName());
}
}
1、属性注入是最简单的,但是这个注入只适用于IoC容器
2、setter注入,是官方早期推荐使用的写法,但是其他语言的setter()方法写法可能不同,通用性不高
3、构造方法注入,是现在官方推荐的写法,其他语言的构造方法基本一致,通用性更高,但是构造方法的参数可能更多,需要注意
@Autowired注解是由spring实现的,而jdk也有对 对象注入的实现:@Resource注解
两个的区别
1、 @Autowired注解是先按照类型获取的 先找User类;@Resource注解先按照名称获取 先找user这个变量名称 后找User类
@Resource
private User user;
2、 @Resource注解不支持构造方法注入;支持属性注入和setter方法注入
3、@Autowired()只支持requied参数设置, @Resource注解支持很多参数设置
此时,要在框架找一个User类型的对象,然后发现存在两个user1和user2,报错
解决方法
1:使用@Resource注解,精确描述BeanName名称,就直接和方法注解的BeanName对应
@Controller
public class UserApplication {
@Resource
private User user1;
public void print() {
System.out.println("user -》" + user1);
}
}
2、使用@Resource注解,使用name属性重命名
@Controller
public class UserApplication {
@Resource(name = "user1")
private User user;
public void print() {
System.out.println("user -》" + user);
}
}
3、@Autowired 搭配@Qualifier注解 @Qualifier注解用于定义名称
@Controller
public class UserApplication {
@Autowired @Qualifier("user1")
private User user;
public void print() {
System.out.println("user -》" + user);
}
}