什么是Spring?
它是一个生态,可以构建java应用所需的一切基础设施,
spring是java企业级的开源容器框架,spring框架是为简化java企业级应用开发,解决企业级应用开发的业务逻辑层和其他各层对象的直接耦合问题
spring是IOC和AOP的容器框架
IOC:控制反转
AOP:面向切面编程
容器:包含并管理应用对象生命周期
Spring是如何简化开发的:
基于POJO的jq轻量级和最小入侵编程
通过依赖注入和面向接口实现松耦合
基于切面和惯例进行声明式编程
通过切面和模板减少样板代码
Spring的优缺点?
优点
方便解耦,简化开发
Spring通过提供的IOC容器,我们可以将对象之间的依赖关系交由Spring控制,避免硬编程所造成的过度程序耦合。
集中管理对象,对象和对象之间的耦合度减低,方便维护对象
AOP编程支持
通过AOP功能 ,支持允许将一些通过任务如安全、事务、日志等进行集中管理,从而提供了更好的复用
在不修改代码的情况下可以对业务代码进行增强,减少重复代码 提高开发效率 方便维护。
声明事务的支持
在spring中 通过声明式方式灵活的进行事务管理,提高开发效率和质量
只需要一个简单注解@Transactional 就可以声明事务
方便测试
Spring实现测试,使我们可以结合junit 非常方便测试 Spring Bean Spring MVC等接口调用
5.方便集成各种优秀框架
Spring有非常大的粘合度、集成能力强,只需要简单配置觉可以集成第三方框架,
(如Struts Hibemate)
6.降低Java EE API的使用难度
Springs对很难的JAVA EE API(如JDBC JAVAMAIL,远程调用)提供一层封装,通过简易封装,使API的使用难度大为降低
简化开发 封装很多功能性代码
7.java源码是经典学习案例
学习到了Spring底层的实现、反射、设计模式 都是值得学习,提供非常非常多的扩展接口供外部进行扩展。
缺点:
从应用层来说没有缺点
简单开发 如果想深入学习非常困难(上层使用越简单 地城设计越复杂)
源码缺点 由于Spring大而q全(要集成z这么多框架、提供非常多的扩展点,进过十多年的代码迭代)代码量十分庞大,一百多万 深入学习y源码有一定的困难
Spring IOC的作用和优点?
IOC控制反转,引入IOC 就将创建对象的控制权交给Spring的IOC,以前有程序员自己去控制对象创建,现在交给Spring的IOC取创建,如果要去使用对象需要通过DI(依赖注入)如@Autowired自动注入,就可以使用对象
优点:集中管理对象,方便维护。
Spring IOC实现机制:
工厂模式+反射
IOC与DI的区别:
IOC是目的 控制反转,DI是手段 依赖注入,IOC把类对象的创建交给spring容器
DI依赖注入,指Spring创建对象的过程,将对象的属性进行赋值
紧耦合和松耦合的区别
紧耦合是指类之间高度依赖
松耦合是通过促进单一职责和关注点分离(接口分离),依赖倒置的设计原则来实现的
接口分离原则:模块之间通过抽象接口隔离开,而不是通过具体的类强耦合起来。
SpringIoc加载过程:看详细视频。
SpringIOC的扩展点及调用时机
Java类的初始化和实例化的区别
类的初始化:是完成程序执行前的准备工作,在这个阶段,静态的(b变量,方法,代码块)
会被执行。同时会开辟一块存储空间存放静态数据。初始化只在类加载的时候执行一次
类的实例化(实例化对象):
是指创建一个对象的过程。这个过程会在堆中开辟内存,将一些非静态的方法,变量存放里面。在程序执行的过程中,可以创建多个对象,即多次实例化。每次实例化都会开辟一块新的内存。
什么是SpringBeans
在Spring中有SpringIoc容器管理的对象称为bean,bean是有一个SpringIOC容器实例化、组装和管理的对象
什么是Javabean :
java的类就是JavaBean,是自己创建的。
配置Bean的哪几种方式:
xml:<bean class="com.tuling" id="">
注解:@Component @Controller @Service @Repostory 这个前提是要扫描b包
javaConfig:@Bean 这个可以自己控制实例化过程

@Import 使用@Import有三种方式。
1.在配置类上配置@Import注解,并定义要创建的bean.class;容器启动后就会自动创建
2.导入ImportSelector实现类,可以注册多个bena
实现了ImportSelector接口,就必须重写 selectImports 方法,如下所示,就会把 TestB 注入IOC 容器,让 Spring 来管理名称为“com.demo.TestB” 的 bean。同理,该方法返回的是一个数组,如果返回多个,就会在 IOC 容器里生成多个 bean
public class MySelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.demo.TestB"};
}
}
3.导入 ImportBeanDefinitionRegistrar实现类,可以注册多个BeanDefinition
跟实现 ImportSelector 不同,实现 ImportBeanDefinitionRegistrar 不是必须重写ImportBeanDefinitionRegistrar 的方法,但是我们为了注入 bean定义, 还是需要重写 registerBeanDefinitions 方法,如下所示,此时就会注入一个名字为 testC 的 bean。同理也可以在该方法里使用多个 RootBeanDefinition 结合 registry 来注入多个 bean定义。
public class MyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//构造 BeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestC.class);
//注册 bean, 并给其取个名字
registry.registerBeanDefinition("testC",rootBeanDefinition);
}
}
代码演示
public class TestA {
private void print() {
System.out.println("TestAAAAAA");
}
}
public class TestB {
private void print() {
System.out.println("TestBBBBBB");
}
}
public class TestC {
private void print() {
System.out.println("TestCCCC");
}
}
定义实现 ImportSelector 的类,用来注入 TestB 的实例
public class MySelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.demo.TestB"};
}
}
定义实现 ImportBeanDefinitionRegistrar 接口的类,用来注入 TestC 的实例
public class MyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//构造 BeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestC.class);
//注册 bean, 并给其取个名字
registry.registerBeanDefinition("testC",rootBeanDefinition);
}
}
定义配置类,通过 @Import 注解注入 bean 实例
@Import({TestA.class, MySelector.class, MyRegistrar.class})
public class ImportDemo {
}
编写测试类
public class ImportMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ImportDemo.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
//打印出 IOC 容器里所有的 bean
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
