之前我们存储Bean时,需要在spring-config中添加一行bean注册内容才行,而现在我们只需要一个注解就可以代替之前要写的一行配置了
在spring-config.xml中添加如下配置:
其中
将对象存储在Spring中,有两类注解类型可以实现:
【类注解使用方法】
@Controller
public class UserController {
public void sayHi(String name) {
System.out.println("Hi," + name);
}
}
这样就将UserController存储到Spring中了。
类注解的功能基本是一样的,都是在类的前面进行注释,就能将相应的类存储到Spring中。但是功能相同,为什么还要这么多种注解呢?
这就是为了让程序员看到类注解之后,就能直接了解当前类的用途了。比如:
程序的工程分层,调用流程如下:
我们已经知道如何存储一个Bean,但是我们应当如何使用呢?
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean("userController", UserController.class);
userController.sayHi("xiaoming");
}
}
通过上面的示例,我们可以看出,bean使用大驼峰的形式命名,而在取出的时候我们使用小驼峰的形式。
我们看一下里面的源码。我们双击Spring搜索关键字:beanName
我们发现它是使用JDK中的方法。命名规则如下:
类注解是添加到类上面的,而方法注解是添加到方法上面的,代码实现如下:
package com.bit.service.model;
import org.springframework.context.annotation.Bean;
/**
* Describe:
* User:lenovo
* Date:2023-07-20
* Time:11:19
*/
public class Uses {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
package com.bit.service.model;
/**
* Describe:
* User:lenovo
* Date:2023-07-20
* Time:11:19
*/
public class User {
private int Id;
private String name;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
我饿们尝试去获取上面的Bean对象:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean("user1", User.class);
System.out.println(user);
}
我们来探究以下原因。
由于一个程序中有很多的类,所有了的方法更是不计其数,如果所有方法都要扫描,效率会大大降低,方法注解要配合着类注解来使用,这样就能提高效率。代码如下:
@Component
public class Uses {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
我们再次尝试获取Bean,这次就成功了。
我们可以通过设置name属性给Bean对象进行重新命名的操作,代码如下:
@Component
public class Uses {
@Bean(name = "user")
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
User user = context.getBean("user", User.class);
System.out.println(user);
}
这个重命名的name实际上是一个数组,一个bean可以有多个名字:
@Component
public class Uses {
@Bean(name = {"user", "user1", "u1"})
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
User user = (User)context.getBean("u1");
System.out.println(user);
}
获取bean对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫做对象注入
对象装配(对象注入)的实现方法以下3中:
属性注入是使用 @Autowired 实现的,将 Service类注入到 Controller类中。
Service类的代码如下:
@Service
public class UserService {
/**
* 根据ID获取用户数据
*
*/
public User getUser(Integer id) {
//伪代码
User user = new User();
user.setId(id);
user.setName("Java-" + id);
return user;
}
}
Controller类的代码如下:
@Controller
public class UserController {
//属性注入
@Autowired
private UserService userService;
public User getUser(Integer id) {
return userService.getUser(id);
}
public void sayHi(String name) {
System.out.println("Hi," + name);
}
}
获取Controller中getUser方法:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean("userController", UserController.class);
System.out.println(userController.getUser(1).toString());
}
这里的关键是我们没有在UserController中创建UserService对象而是使用属性注入的方式直接获取到了这个对象。
构造方法注入式是在类的构造方法中实现注入,如下代码所示:
@Controller
public class UserController2 {
private UserService userService;
//构造方法注入
@Autowired
public UserController2(UserService userService) {
this.userService = userService;
}
public User getUser(Integer id) {
return userService.getUser(id);
}
}
【注意】只有一个构造方法时,那么 @Autowired注解可以省略
但是如果类中有多个构造方法,那么需要添加上@AutoWired来明确指定到底使用哪一个构造方法,否则将会程序报错。
代码如下:
@Controller
public class UserController3 {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser(Integer id) {
return userService.getUser(id);
}
}
【使用方法】
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
UserController3 userController3 = applicationContext.getBean("userController3", UserController3.class);
System.out.println(userController3.getUser(1).toString());
}
在进行类注入时,除了可以使用@Autowired关键字之外,我们还可以使用@Resource进行注入。
@Autowried 和 @Resource的区别
当出现以下多个Bean的时候,饭hi同一个类型时程序就会报错,如下代码:
@Component
public class Uses {
@Bean()
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
@Bean
public User user2() {
User user = new User();
user.setId(2);
user.setName("MySQL");
return user;
}
}
此时我们使用属性注入
@Controller
public class UserController4 {
@Autowired
User user;
public void func() {
System.out.println(user);
}
}
使用这个类
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController4 userController4 = context.getBean("userController4", UserController4.class);
userController4.func();
}
同一类型多个Bean报错处理
在Spring项目中,通过main方法获取到Controller类,调用Controller里卖弄通过注入的方式调用Service类,Service再通过注入的方式获取到Repository类,Repository类里面有一个方法构造构造一个User对象,返回给main方法。Repository无需连接数据库,使用伪代码即可。
【思路】配置好相关文件和相关目录后,创建user设置相关属性,创建UserRepository,并写getUser()方法,创建UserService类,使用构造方法注入的方式,并写getUser()方法调用Repository中的方法,以同样的方式创建UserController。
代码链接:Spring exercises1 · 风夏/JavaEE进阶 - 码云 - 开源中国 (gitee.com)
1. 将对象储存到Spring中:
2. Bean的命名规则:如果 ①字符长度大于1 ②首字母大写 ③第二个字母大写,则使用原类名作为Bean名称;其他情况首字母小写获取名称。
3. 从Spring中获取对象
4. 注入的关键字
5. 解决同一类型多个Bean的报错: