Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC和AOP为内核。含有七大核心模块
(1)Spring Core:核心容器提供了Spring的基本功能。核心容器的核心功能是用Ioc容器来管理类的依赖关系.Spring采用的模式是调用者不理会被调用者的实例的创建,由Spring容器负责被调用者实例的创建和维护,需要时注入给调用者。这是目前最优秀的解耦模式。
(2)Spring AOP:Spring的AOP模块提供了面向切面编程的支持。SpringAOP采用的是纯Java实现。Spring AOP采用基于代理的AOP实现方案,AOP代理由Ioc容器负责生成、管理,依赖关系也一并由Ioc容器管理,尽管如此,Spring Ioc容器并不依赖于AOP,这样我们可以自由选择是否使用AOP。
(3)Spring ORM:提供了与多个第三方持久层框架的良好整合
(4)Spring DAO: Spring进一步简化DAO开发步骤,能以一致的方式使用数据库访问技术,用统一的方式调用事务管理,避免具体的实现侵入业务逻辑层的代码中
(5)Spring Context:它是一个配置文件,为Spring提供上下文信息,提供了框架式的对象访问方法。Context为Spring提供了一些服务支持,如对国际化(i18n)、电子邮件、校验和调度功能。
(6)Spring Web:提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IoC容器初始化和针对Web的applicationContext.
(7)Spring MVC:提供了Web应用的MVC实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和web form之间。并且,还可以借助Spring框架的其他特性
spring中有两种Bean:普通Bean和工厂Bean
spring提供了一个FactoryBean的工厂类接口,可以通过实现接口来实例化Bean
FactoryBean接口中有三个方法
①getObject 获取对象
②getObjectType 获取对象类型
③isSingleton 是否单例
1.xml文件中bean标签配置
2.配置类(springboot支持)
3.注解的方式
4.properties方式
1.通过全类名
<bean name="helloSpring" class="com.qjk.createBean">
<property name="name" value="Spring"></property>
</bean>
2.通过工厂方法
创建类
public class carFactory{
//非静态方法
public Car createCar(){
Car car = new Car();
car.setBrand("QQ");
return car;
}
//静态方法
public static Car createStaticCar(){
Car car = new Car();
return car;
}
}
1.非静态方法createCar的注入方式:必须实例化工厂类后才能调用工厂方法
<bean id="carFactory" class="com.qjk.factory.CarFactory"/>
<bean id="car" factory-bean="carFactory" factory-method="createCar">
bean>
2.静态方法createStaticCar的注入方式
<bean id="car1" class="com.qjk.factory.CarFactory" factory-method="createStaticCar">
</bean>
XMLBeanFactory是一个bean工厂,当spring使用xml创建bean时需要使用。
1.FileSystemXmlApplicationContext :物理路径,此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
2.ClassPathXmlApplicationContext:resources路径下读取,相对路径,此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
3.WebXmlApplicationContext:web.xml定义此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean
bean 定义中的scope属性来定义
1.singleton : bean在每个Spring ioc 容器中只有一个实例。GC不回收spring的单例bean【默认】
2.prototype:一个bean的定义可以有多个实例。 GC回收
3.request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
4.session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
5.global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
1.xml文件中显式配置
ref=“bean的id”
2.通过注解装配 Bean
类上加注解@Component
扫描类@ComponentScan
3.自动装配——@Autowired
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
BeanFactory:是Spring里面最顶层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。BeanFactory 简单粗暴,可以理解为就是个 HashMap,Key 是 BeanName,Value 是 Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容器”。
ApplicationContext 可以称之为 “高级容器”。因为他比 BeanFactory 多了更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如 JSP tag 的支持),对 BeanFactory 多了工具级别的支持等待,该接口定义了一个 refresh 方法,用于刷新整个容器,即重新加载/刷新所有的 bean。
BeanFactory是一个工厂,也就是一个容器,是来管理和生产bean的;
FactoryBean是一个bean,但是它是一个特殊的bean,所以也是由BeanFactory来管理的
它是一个接口,他必须被一个bean去实现,不过FactoryBean不是一个普通的Bean,它会表现出工厂模式的样子,是一个能产生或者修饰对象生成的工厂Bean
首先应该定义Bean,定义Bean的常用方式有三种,(xml,注解,properties)
定义后通过实现BeanDefinitionReader接口来读取Bean的定义
在读取完bean的定义后通过实现BeanFactoryPostProcessor接口对Bean进行增强处理
然后通过反射的方式创建Bean
在对Bean进行初始化操作,通过执行set方法对属性赋值
在属性初始化后执行BeanPostProcessorBefore也就是Bean的前置增强处理
前置处理增强后调用Bean的init方法初始化
初始化后的执行BeanPostProcessorAfter也就是Bean的后置处理
后置处理后就是完整的Bean
1.减少了新生成实例的消耗新生成实例消耗包括两方面,第一,spring会通过反射或者cglib来生成bean实例这都是耗性能的操作,其次给对象分配内存也会涉及复杂算法。 提供服务器内存的利用率 ,减少服务器内存消耗
2.减少jvm垃圾回收由于不会给每个请求都新生成bean实例,所以自然回收的对象少了。
3.可以快速获取到bean因为单例的获取bean操作除了第一次生成之外其余的都是从缓存里获取的所以很快。
不是,Spring框架中的单例bean不是线程安全的
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了
举例
A类:属性B类 B b;找B类型的对象赋值,找不到就等
B类:属性A类 A a;找A类型的对象赋值,找不到就等
互相等待
当A类需要b找不到b时 会对其进行标记,继续往下走 B找a时也是一样 。
spring有监听回调的机制当A监听发现B创建完成后在把属性值附上这样就不会产生循环依赖
springIOC我们称之为控制反转,在没有使用IOC之前我们需要自己取创建和管理对象,代码的耦合性比较高,在使用了IOC之后Bean对象的创建和管理都交给spring进行,大大降低了耦合度。
<beans>
<import resource=“resource1.xml” />//导入其他配置文件Bean的定义
<import resource=“resource2.xml” />
<bean id="userService" class="cn.lovepi.***.UserService" init-method="init" destory-method="destory">
bean>
<bean id="message" class="java.lang.String">
<constructor-arg index="0" value="test">constructor-arg>
bean>
beans>
@Component:当对组件的层次难以定位的时候使用这个注解
@Controller:表示控制层的组件
@Service:表示业务逻辑层的组件
@Repository:表示数据访问层的组件
1.使用@Configuration注解需要作为配置的类,表示该类将定义Bean的元数据
2.使用@Bean注解相应的方法,该方法名默认就是Bean的名称,该方法返回值就是Bean的对象。
3.AnnotationConfigApplicationContext或子类进行加载基于java类的配置
@Configuration
public class BeansConfiguration {
@Bean
public Student student(){
Student student=new Student();
student.setName("张三");
student.setTeacher(teacher());
return student;
}
@Bean
public Teacher teacher(){
Teacher teacher=new Teacher();
teacher.setName("李四");
return teacher;
}
}
public class TestCreateBean{
public static void main(String args[]){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeansConfiguration.class);
Student student = (Student) context.getBean("student");
Teacher teacher = (Teacher) context.getBean("teacher");
System.out.println("学生的姓名:" + student.getName() + "。老师是" + student.getTeacher().getName());
System.out.println("老师的姓名:" + teacher.getName());
}
}