发表于: 2020-07-01 22:38:59
1 1765
今天完成的事情
1. 看书
遇到的问题
无
收获
- spring container
容器是 spring 的核心,spring 容器有很多种实现,可以分为两类:bean Factory 与 ApplicationContext
bean 工厂提供最简单的 DI,ApplicationContext 是基于 bean 工厂构建的服务。
应用上下文,昨天只看了和 java config 相关的。
Spring 自带了很多种应用上下文,常见的有如下几种:
AnnotationConfigApplicationContext:从一个或者多个基于 java 的配置类中加载 spring 上下文
AnnotationConfigWebApplicationContext:从一个或者多个基于 java 的配置类中加载 Spring Web 应用上下文
ClassPathXmlApplicationContext:从类路径下的一个或者多个 xml 配置文件中加载上下文定义,把应用上下文的定义文件作为类资源
FileSystemXmlApplicationContext:从文件系统下的一个或者多个 xml 配置文件中加载上下文定义,把应用上下文的定义文件作为类资源
XmlWebApplicationContext:从 web 应用下的一个或者多个 xml 配置文件中加载上下文的定义
- Spring 配置方案
a,xml 中显式配置
b,java 中显式配置
c,隐式的 bean 发现机制与自动装配
自动化装配 bean:
a,组件扫描(component scanning):Spring 会自动发现应用上下文中创建的 bean
b,自动装配(autowiring):Spring 自动满足 bean 之间的依赖
Xml 开启自动扫描
<context:component-scan base-package="cn.mogeek"/>
Java 开启自动扫描
@configuration // 声明为配置类
@ComponentScan // 启用组件扫描
Public class AppConfig{ }
类名不重要,只是提供给注解附着。
@ComponentScan 默认会扫描所附着的配置类所在的包及其下的子包,查找带 @Component 注解的类,并为其创建 bean
扫描多个包/扫描其他包
@ComponentScan(basePackages={"cache", "service"})
Bean 的命名,这个在 xml 配置就是配置一个 id
如果我们不配置的话,spring 会默认分配一个 id,即首字母小写后的类名。
在 java 配置类中想要自定义 id 只需要在 @Component 后加上自定义 id 即可。
@Component("cd")
public class CompactDisc{
···
}
自动装配 @Autowired
这个注解可以用在构造器上,也可以用在属性的 Setter 方法上。
@Autowired
public Service(Dao dao){
this.dao = dao;
}
@Autowired
public void setDao(Dao dao){
this.dao = dao;
}
命名不一定都是要 set,spring 中自动装配的 set 方法是泛指所有的注入参数的方法,改成 insertDao(Dao dao) 也是一样的效果。
不管方法如何命名,只要带上这个注解,spring 都会尽量满足所需的注入参数,如果方法所需要的 bean 没找到,那么在创建应用上下文的时候就会报一个异常。为了避免这个异常,我们可以设置 @Autowirde(required=false) 这样 spring 没找到也不会报错,但是我们自己使用的时候就要注意空指针异常了。
@Autowired 注解属于 spring,我们可以使用 java 依赖注入规范的 @Inject 注解来代替。同时这个规范还提供了 @Named 注解可以用于代替 @Component。使用上会有一些差别。
Java 代码装配 bean:
首先我们需要创建一个配置类,很简单,带上 @Configiration 注解就好,然后我们就可以在其中声明 bean 了。
@Configuration // 声明为一个配置类
public class AppConfig{
@Bean // 声明为 bean
public Dao getDao(){
return new Dao();
}
@Bean
public Service getService(){
Return new Service(getDao());
}
}
在上面的示例代码中,有一点需要注意。Service 内部调用了 getDao() 这个方法但是并不会重新 new 一个 dao 对象。因为 getDao() 方法已经加上 @Bean 注释声明为一个 bean 了,spring 就会拦截所有的调用,然后赋给调用者一个现有的实例化对象。
这种写法与其实际的行为可能比较容易让人误解,还可以换一种比较不容易误解的写法
@Bean
public Service getService(Dao dao){
return new Service(dao);
}
明天的计划
1. 看书
评论