前言
什么是spring
Spring是一个使用JavaBean,全方位整合各个组件,实现一站式开发的企业级应用的框架,说白了,就是一个兼容器,兼容各种开发的组件使得开发便捷高效!
spring体系架构
简单说明,spring包含的常用的重要的封装
IOC容器,管理所有的bean对象,降低组件之间的耦合
封装AOP技术,标准且便捷了切面开发编程
提供了事务管理,消息服务
提供了辅助类包括jdbcTemplate,便捷我们对数据库操作
支持几乎所有主流框架如shiro,mybatis等
各种类型Bean的作用域讲解
- singleton单例,默认的作用域且只有一个不会多次创建,且项目启动就已经初始化进行容器管理了
- prototype,每次创建新的对象,且项目启动不会加载,容器也不会管理其声明周期
- request对象,在request作用域范围内
- session对象,在session作用域范围内
- application对象,global-session在一个应用范围内
- websocket对象,在webSocket作用域范围内
Bean的生命周期(以xml配置bean给ioc容器为例,演示其生命周期)
基本流程
类加载–>实例化–>属性填充–>初始化–>使用–>销毁
类加载:java文件通过编译器变成了.class文件,接下来类加载器又将这些.class文件加载到JVM中。其中类装载器的作用其实就是类的加载
实例化:实例化一般是由类创建的对象,在构造一个实例的时候需要在内存中开辟空间
初始化:初始化其实是为对象变量分配内存空间,并确定其初始值的过程,static变量和static语句块优于普通变量和构造函数先执行
public class IocPerson {
private String name;
private int age=staticTest();
private String address;
public IocPerson() {
System.out.println("无参构造器运用");
}
public IocPerson(String name) {
this.name = name;
}
public void saySomething(String message){
System.out.println(name+"说:"+message);
}
public void init(){
System.out.println(name+"初始化了");
}
public void destory(){
System.out.println(name+"销毁了");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("name属性赋值");
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public static int staticTest(){
System.out.println("静态方法的最先执行");
return 18;
}
@Override
public String toString() {
return "IocPerson{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
<bean id="IocPerson7" class="org.yangz.entity.IocPerson"
init-method="init" destroy-method="destory" >
<property name="name" value="小杨"></property>
<property name="address" value="广东深圳"></property>
</bean>
静态方法的最先执行
无参构造器运用
name属性赋值
小杨初始化了
小杨说:我可以使用了
小杨销毁了
实例化拓展
实现InstantiationAwareBeanPostProcessor接口可以对实例化前后进行拓展
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("实例化之前执行的方法");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("实例化之后执行的方法");
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("实例化之后进行属性赋值,既依赖注入(DI)"+pvs);
return pvs;
}
}
初始化拓展
实现BeanPostProcessor接口可以对初始化过程进行拓展
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之前执行");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之后执行");
return bean;
}
}
总结
上面拓展后的bean加载对应的接口,然后演示bean生命周期如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="IocPerson7" class="org.yangz.entity.IocPerson"
init-method="init" destroy-method="destory" >
<property name="name" value="小杨"></property>
<property name="address" value="广东深圳"></property>
</bean>
<bean class="org.yangz.entitys.MyBeanPostProcessor"></bean>
<bean class="org.yangz.entitys.MyInstantiationAwareBeanPostProcessor"></bean>
</beans>
静态方法的最先执行
无参构造器运用
实例化之后执行的方法
实例化之后进行属性赋值,既依赖注入(DI)PropertyValues: length=2; bean property 'name'; bean property 'address'
name属性赋值
初始化之前执行
小杨初始化了
初始化之后执行
小杨说:我可以使用了
小杨销毁了
所以总结bean的生命周期应该可以是:类加载–>InstantiationAwareBeanPostProcessor–>实例化InstantiationAwareBeanPostProcessor–>静态常量赋值–>属性填充–>BeanPostProcessor–>初始化–>BeanPostProcessor–>使用–>销毁
*详细周期说明:java文件被编译成.class文件后,类加载器把.class文件加载到jvm中,就是类加载,bean容器在内存中开辟空间,通过反射,构造一个类对应的实例就是实例化过程,相当于人类出生了,出生前后比如胎教,比如上户口,是对这个实例对象的一些增强设置就是实例化前后拓展接口的作用。然后是属性填充,类似给婴儿起名字,穿衣服等,也就是对实例化对象的属性进行赋值,也是依赖注入DI过程(依赖注入的三种方式下面会详细说明)。下面开始初始化,初始化相当于上学获得相应技能的全过程,首先是通过*Awre接口,对实例对象进行增强设置属性,类似起学名,选学校,processor接口执行初始化前方法,类似入学报名,InitializingBean接口对属性进行校验,类似开学登记,然后就是Bean对象指定的初始化方法被调用,真正的学习技能方法类型学习过程,初始化后置处理器,指定指定方法类似毕业领证。再到最后不被社会需要,执行销毁方法,destory被埋了。
基于注解操作bean对象
会扫描加入IOC的注解包括有:@Controller、@Service、@Component、@Mapper(Mybatis的注解,替换原始的@Repository便捷一些)、@PostConstruct注解
在Spring Boot项目中,其会默认扫描【启动类所在的包以及其子包中的类,然后把其实例化为bean,使用IoC管理起来】;(其他的包是不会扫描的;如果还想让其扫描其他的包,就需要使用@ComponentScan去指定,否则就不会把那些bean交到spring管理。)
在spring中还要.xml配置扫描地址