Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于JEE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
springIOC 叫控制反转 Inversion of Control 同时又称为 DI 依赖注入,主要负责:实例化,配置和组装Bean,容器通过读取配置元数据获取有关要实例化,配置和组装哪些对象的指令。
配置元数据的方式有3种方式,分别为:基于XML的配置方式,基于注解的配置方式,基于Java类的配置方式
基于XML的配置方式:
基于注解的配置方式:
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
}
基于Java类的配置方式:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
spring官网描述:
1、ApplicationContext ac = new ClassPathXmlApplicationContext("/WEB- INF/applicationContext.xml");
2、ApplicationContext ctx = new FileSystemXmlApplicationContext("/WEB-INF/applicationContext.xml");
1.用构造函数实例化
2.用静态工厂方法实例化
3.使用实例工厂方法实例化
依赖注入(DI)是一个过程,通过该过程,对象只能通过构造函数参数,工厂方法的参数或在构造或创建对象实例后在对象实例上设置的属性来定义其依赖关系。从工厂方法返回,然后,容器在创建bean时注入那些依赖项从根本上讲,此过程是通过使用类的直接构造或服务定位器模式来控制其自身的实例化或位置的Bean本身的逆过程(因此称为控制反转)
依赖注入的方式:
基于构造函数的依赖注入和基于Setter的依赖注入,其余的都是这两种方法的变体。比如@Autowired 属于field.set 也属于set的一种变体。
自动注入模型byName和byType找到了会需要通过setter方式注入。constructor自动注入模型会需要通过构造函数方式注入,默认是空参构造,如果有多个带参构造,选择最多带参构造。
自动注入模型byName是判断setter方法名小写,找bean。byType通过setter方法的属性类型找bean。
spring的自动注入,是通过java的内省机制。
8、@Autowried和@Resource
1、还有注解注入@Autowried和@Resource,理论上他们算手动注入,不算自动注入。最主要的是,通过代码调试我们在bean上加上@Component的注解,默认BeanDefinition的autowireMode为0,就是不开启自动注入,而通过加@Autowried或者@Resource注解,并没改变该BeanDefinition的autowireMode值,依然注入模型为0。例子:
@Component
public class A {
@Autowired
private B b;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
GenericBeanDefinition bd = (GenericBeanDefinition)ac.getBeanDefinition("a");
System.out.println(bd.getAutowireMode());
}
输出结果为 0。
2、并且自动注入模型byName和byType找不到bean,不会注入也不会报错,找到多个会报错。而通过注解方式,比如@Autowried先通过bean类型找到多个,会继续通过bean名称找,找不到或者找到多个会报错。
@Autowried和@Resource 区别
1、@Autowried是spring的注解,@Resource是jdk的注解,他是先判断bean类型,再判断bean名称,找多个后选的bean,再通过属性名去推断bean。@Autowried是通过bean的后置处理器AutowiredAnnotationBeanPostProcessor注入,@Resource是通过CommonAnnotationBeanPostProcessor。
注意点他们如果同一个方法都只会执行一次,@PostConstruct在开启注解下才能用
1. @PreDestroy注解,
2. 实现DisposableBean接口
3. xml 加destroy-method
实例化完bean回调顺序
销毁bean回调顺序
官方文档参考如下:
smartlifeCycle -->继承 Lifecycle
Lifecycle接口的方法
void start(); //容器启动之后执行
void stop(); //容器结束执行,需要isRunning返回true
boolean isRunning(); //是否执行stop
SmartLifecycle接口本身的方法
boolean isAutoStartup(); //返回true 自动自行start(),否则start需要手动调用才会执行
void stop(Runnable callback); //这是smartlifecycle 特有的, 有了他,就不会执行上面父类的stop
Phased接口的方法
int getPhase(); //如果项目中有多个实现了SmartLifeCycle类 按从小到大执行顺序
1、singleton :当您定义一个bean定义并且其作用域为单例时,Spring IoC容器将为该bean定义所定义的对象创建一个实例。该单个实例存储在此类单例bean的缓存中,并且对该bean的所有后续请求和引用都返回缓存的对象
2、prototype:Bean部署的非单一原型范围会在每次请求特定bean时创建一个新bean实例。也就是说,将Bean注入到另一个Bean中,或者您可以通过getBean()
容器上的方法调用来请求它。通常,应将原型作用域用于所有有状态Bean,将单例作用域用于无状态Bean。
2.1、Spring不管理原型Bean的完整生命周期。
2.2、原型的情况下,不会调用已配置的销毁生命周期回调。
2.3、客户端代码必须清除原型作用域内的对象,并释放原型Bean拥有的昂贵资源。为了使Spring容器释放原型作用下的bean所拥有的资源,请尝试使用自定义bean后置处理器,其中包含对需要清理的bean的引用
3、request:将单个bean定义的范围限定为单个HTTP请求的生命周期。也就是说,每个HTTP请求都有一个在单个bean定义后面创建的bean实例
4、session:将单个bean定义的范围限定为HTTP的生命周期Session
5、application:将单个bean定义的作用域限定为的生命周期ServletContext
例子:
appPreferences
bean的作用域在ServletContext
级别上,并存储为常规 ServletContext
属性
他与单例的区别是:
它是每个单例ServletContext
,而不是每个Spring'ApplicationContext
6、wbsocket:将单个bean定义的作用域限定为的生命周期WebSocket
与任何自定义范围一样,Spring MyBean
首次在控制器中对其进行访问时会初始化一个新实例,并将该实例存储在WebSocket会话属性中。随后将返回相同的实例,直到会话结束。WebSocket范围的bean调用了所有Spring生命周期方法
!在request
,session
,application
,和websocket
范围只有当你使用一个基于web的Spring可ApplicationContext
实现(例如 XmlWebApplicationContext
)。如果您将这些作用域与常规的Spring IoC容器(例如)一起使用ClassPathXmlApplicationContext
, 则会报异常:an IllegalStateException
that complains about an unknown bean scope is thrown.