我们现在已经可以实现基本的Spring读取和存储对象的操作了,但在操作过程当中。我们发现并没有那么简单。在Spring当中想要更简单的存储和使用对象的核心是使用注解接下了就了解下,如何使用注解来存储和获取Bean
之前存储Bean对象,需要添加一行bean才能注册,如下图所示:
而现在只需要一个注解,就可以代替一行的配置,但是我们先要来点准备工作
注意:想要把Bean成功的存储到Spring当中,我们需要配置一下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确识别并保存到Spring当中
在spring-config.xml
当中添加如下配置:
圈起来的是扫描路径,表示所有要存放到Spring中的Bean的根目录
想要将对象存储到Spring当中,有两种注解类型可以实现:
@Controller @Service @Repository @Component @Configuration
@Bean
接下来,分别来看:
@Controller
public class UserController {public void sayHi() {System.out.println("你好Controller");}
}
这时我们按照之前的方法获取到Spring中的Bean
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean("userController", UserController.class);
userController.sayHi();
@Service
public class UserService {public void sayHi() {System.out.println("你好Service");}
}
@Repository
public class UserRepository {public void sayHi() {System.out.println("你好Repository");}
}
@Component
public class UserComponent {public void sayHi() {System.out.println("你好Component");}
}
@Configuration
public class UserConfiguration {public void sayHi() {System.out.println("你好Configuration");}
}
既然功能都是一样的,为什么需要这么多呢?
这和为什么每个省/市都有自己的车牌号是一样的?比如陕西车牌号就是:陕XXXXXX,北京车牌号是:京XXXXXXXX。甚至一个省不同的县区车牌号都是不一样的。这样做的好处就是节约了号码,更重要的是可以直观的标识一辆车的归属地
那么为什么需要这么多类的注解也是相同的原因,就是让程序员看到类注解之后,就直接了解当前类的用途。
让代码的可读性提高,让程序员能够直观的判断当前类的用途
比如:
@Controller
表示业务逻辑层@Service
表示服务层@Repository
表示持久层@Configuration
表示配置层程序的工程分层,调用流程如下:
查看@Controller、@Service、@Repository、@Configuration
等注解可以发现:
这些类注解里面都有一个注解@Component
,说明它们本身就属于@Component
的“子类”
通过场面的例子我们可以看出,通常我们bean使用的都是标准大驼峰的命名,而读取的时候首字母小写就可以获取到bean了。
然后当我们首字母和第二个字母都大写的时候,就不能正常的读取到Bean了
这个时候我们就要查询Spring关于Bean存储时生成的命名规则了
源码如下:
public static String decapitalize(String name) {if (name == null || name.length() == 0) {return name;}if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&Character.isUpperCase(name.charAt(0))){return name;}char chars[] = name.toCharArray();chars[0] = Character.toLowerCase(chars[0]);return new String(chars);
}
类注解是添加到某个类上的,而方法注解是放到某个方法当中,如以下代码实现:
public class UserBean {@Beanpublic void sayHi() {System.out.println("你好bean");}
}
但是我们发现根本获取不到。这是为什么?
在Spring框架当中,方法注解@Bean要配合类注解才能将对象正常的存储到Spring容器当中,如下代码:
@Component
public class UserBean {@Beanpublic User getUser() {User user = new User();user.setId(1);user.setName("张三");return user;}
}
可以通过设置name属性给Bean对象进行重命名操作
@Component
public class UserBean {@Bean(name = "user")public User getUser() {User user = new User();user.setId(1);user.setName("张三");return user;}
}
Bean命名规则:当没有设置name属性的时候,那么bean默认的名称就是方法名,当设置了name属性之后,只能通过重命名的那么属性对应的值来获取。也就是说,重命名之后再使用方法名就获取不到了
获取bean对象也叫对象装配,是把对象取出来放到某个类当中,也时候也叫作对象注入
对象装配的实现有以下3中方法:
如果当前类当中只存在一个构造方法,那么@Autowired注解可以省略
@Autowired和@Resource的区别:
解决方案有以下两种:
@Controller
public class UserController5 {// 注⼊@Autowired@Qualifier(value = "user2")private User user;public User getUser() {return user;}
}