依赖注入(DI)的迭代实现
Spring 容器可以在不使用<constructor-arg>和<property> 元素的情况下自动装配相互协作的 bean 之间的关系
1、目的:这有助于减少编写一个大的基于 Spring 的应用程序的 XML 配置的数量。
2、方法:你可以使用<bean>元素的 autowire 属性为一个 bean 定义指定自动装配模式。
3、"byName":它尝试将它的属性与配置文件中定义为相同名称的 beans 进行匹配和连接。(注入id唯一)
例子:. java文件
public class A {
private B b;
private C c;
public void setB (B b) {
this.b = b;
}
public void setName(C c) {
this.c = c;
}
}
b通过 'byName' 方式自动装配,而c通过property 注入
<bean id="a" class="xxx" autowire="byName">
<property name="c" value="xxx" />
</bean>
<bean id="b" class="xxx">
</bean>
4、"byType":它的 type 恰好与配置文件中 beans 名称中的一个相匹配。(class要唯一)
5、"constructor":它尝试把它的构造函数的参数与配置文件中 beans 名称中的一个进行匹配和连线。~~
基于注释实现依赖(连线):
1、@Required 注释:应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Required
public void setA(A a) {
this.a = a;
}
2、@Autowired 注释:当 Spring遇到一个在 字段 或 setter 方法 中使用的 @Autowired 注释,它会在方法中执行 byType 自动连接(装配)。如果查询的结果不止一个,那么@Autowired会通过ByName名称来查找。
(1)你可以在属性中使用 @Autowired 注释来除去(替代) setter 方法。Spring 会将这些传递过来的值或者引用自动分配给那些属性。(革新)
@Autowired
private A a;
(2)一个有参构造函数 使用@Autowired 说明当创建 bean 时,即使在 XML 文件中没有使用 property 元素配置 bean ,构造函数也会被自动连接。
(3)@Autowired 的(required=false)选项关闭 默认 行为(必须建立依赖)。
3、@Resource 注释:默认按照 byName 自动装配,名称可以通过name属性进行指定,当找不到与名称匹配的bean时才按照 byType 进行装配。但是如果name属性一旦指定,就只会按照名称进行装配。
4、@Qualifier 注释:当你创建多个具有相同类型的 bean 时,并且想要用它们其中的一个进行装配。
解决:你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱。
@Autowired
@Qualifier("a1")
private Student a;
<bean id="a1" class="xxx">
<property name="xxx" value="xxx" />
</bean>
<bean id="a2" class="xxx">
<property name="xxx" value="xxx" />
</bean>
基于注释实现注入(布线):
1、目的:用注释实现注册bean,简化代码,减少XML文件的代码量。
2、方法:引入component的扫描组件,取替XML中注册bean,多个包用逗号隔开。
<context:component-scan base-package="xxx">
3、如果某个类的头上带有特定的注解@Component/@Repository/@Service/@Controller,就会将这个对象作为Bean注册进Spring容器,其他的类才可以将你作为一个成员变量自动注入。[注册id默认类名且首字母小写,用@Controller(id:"xxx")可改变]
4、@Service用于标注业务层组件
@Controller用于标注控制层组件
@Repository用于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
基于@Configuration 注释实现Java配置类:
1、目的:取代整个原始的XML文件,用Java配置spring并启动spring容器。(底层是一个@Component 注释)
2、使用条件:@Configuration不可以是final类型;@Configuration不可以是匿名类;嵌套的configuration必须是静态类。
3、加载方式:用AnnotationConfigApplicationContext()替换ClassPathXmlApplicationContext()
4、 @Bean 注释:在方法上(返回某个实例的方法),
等价于spring的xml配置文件中的<bean>,作用为:注册bean对象(1.0布线)
@ComponentScan("com.xxx")扫描组件 + @Component注册Bean(2.0布线)
5、 @Configuation等价于<Beans></Beans>
@Bean等价于<Bean></Bean>
@ComponentScan等价于<context:component-scan base-package="com.xxx"/>
@Import(xxx.class)等价于<import/>
@ImportResource("xxx.xml"),组合多个配置类。
抽象结果:1.0时代:在XML中注入(布线),完成依赖(连线)
实现:布线:<bean/>,连线:<property> 到 <autowire>
2.0时代:在Java中仅使用注释,就可以完成依赖注入。
前提:需要在XML中添加约束,引入扫描组件。
3.0时代:用注释使得JavaConfig类完美取代XML
改革:从XML配置过渡到纯Java时代(卖个关子:SpringBoot)