目录
1.1配置spring.xml设置spring存入对象的根路径
2.1解决办法1:使用@Resource(name=‘别名’)
1.Spring 更简单的存储对象(使用注解)
1.1配置spring.xml设置spring存入对象的根路径
(此处的base-package=" com.**"的路径要和根路径一致)
<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) -->
<content:component-scan base-package=""></content:component-scan>
</beans>
1.2使用注解将Bean对象存储到spring中
1)类注解:@Controller控制器(对象的存储)
@Service服务器
@Respository(仓库存储)
@Component(组件存储)(其余四个类注解都是它的子类)
@Configuration(配置存储)
代码示例:(五类注解用法一样)
package com.wwzz.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
/**
* 这个方法只是用来测试的
* @param name
*/
public void SayHello(String name){
System.out.println("Hello! " + name);
}
}
package com.wwzz;
import com.wwzz.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//读取存入对象的id默认情况下要小写
UserController userController = context.getBean("userController", UserController.class);
userController.SayHello("Controller");
}
}
2)方法注解:
@Bean
首先创建一个类User
public class User {
public int id;
public String name;
public int age;
// ... 一堆 getter和setter
}
创建一个UserBean
package com.wwzz.util;
import com.wwzz.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBean {
@Bean
public User user() {
// 伪代码 获取数据库中的内容....
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(18);
return user;
}
}
测试这个注解读取到bean的代码
1.3方法注解重命名Bean
(Spring默认是类扫描,要想使用方法注解@Bean就需要配合类注解@Component一起使用,才能将方法返回对象顺利存储到Spring中)
(重命名之后,方法名就无法使用了)
import com.wwzz.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBean {
//对方法名重命名为“u1”,“u2”
@Bean(name = {"u1","u2"})
public User user() {
// 伪代码 获取数据库中的内容....
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(18);
return user;
}
}
2.Spring更简单的获取对象
获取Bean对象也叫作对象分配,是把对象取出来放到某个类中,有时候也叫对象注入
(在进行注入的时候,可以使用@Autowired关键字,也可以使用@Resource关键字,但是@Resource无法进行构造方法注入)
区别:
1)出生不同:@Autowired来自Spring框架,@Resource来自JDK
2)作用范围不同:@Autowired可以进行属性注入, 构造方法注入, Setter 注入,@Resource可以进行 属性注入, Setter注入, 不能使用构造方法注入
3)功能不同:相比于@Autowired,@Resource支持更多的参数设置,例name设置,根据名称获取Bean
2.1对象装配(对象注入)的实现方法有3种
1)属性注入
2)构造方法注入
3)Setter注入
属性注入:
package com.wwzz.controller;
import com.wwzz.model.User;
import com.wwzz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
// 1. 属性注入 从Spring 中获取一个对象, 并注入到当前类
@Autowired
private UserService userService;
public User findUserById(Integer id) {
if (id == null){
return new User();
}
return userService.findUserById(id);
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController controller = context.getBean("userController",UserController.class);
User user = controller.findUserById(1);
System.out.println(user);
}
构造方法注入:(如果当前类里构造方法只有一个,那么@Autowired是可以被省略的)
package com.wwzz.controller;
import com.wwzz.model.User;
import com.wwzz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
private UserService userService;
// 方法二: 构造方法注入是在类的构造方法种实现注入
@Autowired
public UserController2(UserService userService) {
this.userService = userService;
}
public User findUserById(Integer id){
if(id == null){
return null;
}
return userService.findUserById(id);
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController2 userController2 = context.getBean("userController2",UserController2.class);
User user = userController2.findUserById(1);
System.out.println(user);
}
Setter注入:
package com.wwzz.controller;
import com.wwzz.model.User;
import com.wwzz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController1 {
// 1. 将 UserService 注入到当前类(使用Setter)
private UserService userService;
@Autowired // 必须要添加
public void setUserService(UserService userService) {
this.userService = userService;
}
// 2. 新建一个方法, 在方法里面调用 UserService 的查询方法. 返回用户对象
public User findUserById(Integer id){
if(id == null){
return null;
}
return userService.findUserById(id);
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController1 userController1 = context.getBean("userController1",UserController1.class);
User user = userController1.findUserById(1);
System.out.println(user);
}
3.1三种注入方式的优缺点
属性注入:
优点:简洁使用方便
缺点:只能用于loc容器,如果是非loc容器不可用,并且只有在使用能够的时候才会出现NPE(空指针异常)
构造方法注入:Spring官方推荐的注入方式
优点:通用性,在使用之前一定能保证注入的类不为空
缺点:如果有多个注入会显得比较臃肿
Setter注入:通用性不如构造方法
2.2同一类型多个@Bean报错
package com.wwzz.util;
import com.wwzz.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBean {
@Bean
public User user1() {
// 伪代码 获取数据库中的内容....
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(18);
return user;
}
@Bean
public User user2() {
User user = new User();
user.setId(2);
user.setName("李四");
user.setAge(20);
return user;
}
}
在另一个类中获取User对象:
package com.wwzz.controller;
import com.wwzz.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController5 {
@Resource
private User user;
public User getUser() {
return user;
}
}
以上代码会报错,原因是:获取Bean对象的方法,比如他们首先从名称获取,如果获取不到,就会从类型获取,上面的代码,从名称获取不到,类型又有多个,就会注入失败
2.1解决办法1:使用@Resource(name=‘别名’)
package com.wwzz.controller;
import com.wwzz.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController5 {
//使用别名
@Resource(name='user3')
private User user;
public User getUser() {
return user;
}
}
2.2解决办法2:使用@Qualifier注解定义名称
这里配合@Autowired 和 @Resource 都可以
package com.wwzz.controller;
import com.wwzz.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController5 {
//@Qualifier注解定义名称
@Resource
@Qualifier(value="user3")
private User user;
public User getUser() {
return user;
}
}