Spring的两个核心特性:依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)
Spring的使命:简化Java开发
为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
- 基于POJO的轻量级和最小侵入性编程;
- 通过依赖注入和面向接口实现松耦合;
- 基于切面和惯例进行声明式编程;
- 通过切面和模板减少样板式代码。
目的是松耦合 ,关键是如何进行装配:
方法1.XML的配置
方法2.基于Java的配置
----------------------------------------------------------------------------------------------------------------
允许把遍布应用各处的功能分离出来形成可重用的组件,确保POJO的简单性。
在xml文件中配置 把Minstrel声明为一个Spring切面
---------------------------------------------------------------------------------------------------------------------------
Spring旨在通过模板封装来消除样板式代码。Spring的JdbcTemplate使得执行数据库操作时,避免传统的JDBC样板代码成为了可能。
例:旧的,不适用模板的连接数据库查询操作
使用模板进行查询:
-------------------------------------------------------------------------------------------------------------------------------
对象生存于Spring容器(container)中。
Spring自带了多个容器实现,可以归为两种不同的类型:
- bean工厂(由org.springframework. beans.factory.eanFactory接口定义)是最简单的容器,提供基本的DI支持。
- 应用上下文(由org.springframework.context.ApplicationContext接口定义)基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。(更高级,更常使用)
例如,如下代码展示了如何加载一个FileSystemXmlApplicationContext:
类似地,可以使用ClassPathXmlApplicationContext从应用的类路径下加载应用上下文:
如果想从Java配置中加载应用上下文,那么可以使用AnnotationConfigApplicationContext
在这里没有指定加载Spring应用上下文所需的XML文件,AnnotationConfig-ApplicationContext通过一个配置类加载bean。
应用上下文准备就绪之后,就可以调用上下文的getBean()方法从Spring容器中获取bean。
1.Spring对bean进行实例化;
2.Spring将值和bean的引用注入到bean对应的属性中;
3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法;
4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
5.如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法;
7.如果bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,如果bean使用initmethod声明了初始化方法,该方法也会被调用;
8.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法;
9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。
---------------------------------------------------------------------------------------------------------------------------------
装配:创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质
配置Spring容器最常见的三种方法:
- 在XML中进行显式配置。
- 在Java中进行显式配置。
- 隐式的bean发现机制和自动装配
建议是尽可能地使用自动配置的机制。显式配置越少越好
Spring从两个角度来实现自动化装配:
例:带有@Component注解的CompactDisc实现类
组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean:
另外,还可以通过XML来启用组件扫描,使用Spring context命名空间的
默认是将类名的第一个字母变为小写。如果想为这个bean设置不同的ID,你所要做的就是将期望的ID作为值传递给@Component注解。比如说,如果想将这个bean标识为lonelyHeartsClub,那么你需要将SgtPeppers类的@Component注解配置为如下所示:
另外,还有一种:@Named (不常用)
有一个原因会促使我们明确地设置基础包,那就是我们想要将配置类放在单独的包中,使其与其他的应用代码区分开来。如果是这样的话,那默认的基础包就不能满足要求了。
为了指定不同的基础包,所需要做的就是在@ComponentScan的value属性中指明包的名称:
如果你想更加清晰地表明你所设置的是基础包,那么你可以通过basePackages属性进行配置:
如果想设置多个基础包,只需要将basePackages属性设置为要扫描包的一个数组即可:
除了将包设置为简单的String类型之外,@ComponentScan还提供了另外一种方法,那就是将其指定为包中所包含的类或接口:
自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行自动装配,可借助Spring的@Autowired注解。
eg:通过自动装配,将一个CompactDisc注入到CDPlayer之中
注意:@Autowired是Spring特有的注解。如果不愿意在代码中到处使用Spring的特定注解来完成自动装配任务的话,那么可以考虑将其替换为@Inject: