Spring中管理Bean以及解析XML

时间:2022-06-17 13:01:32

Spring是分层的轻量级框架

以IoC(Inverse of Control 反转控制)和AOP(Aspect Oriented Programming 面向切面编程)为核心

应用Spring的好处:

方便解耦,简化开发

Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无需手动编程

方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis等)的直接支持

降低JavaEE API的使用难度

Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

Spring的实例化Bean有三种方式:

使用类构造器直接实例化(常用)

<bean id="userBean1" class="com.szy.spring.implbean.UserBean" />

使用静态工厂的方法实例化

<bean id="userBean2" class="com.szy.spring.factory.BeanFactory" factory-method="UserBeanService" />

使用实例工厂方法实例化

<bean id="factory" class="com.szy.spring.factory.BeanFactory" />

<bean id="userBean3" factory-bean="factory" factory-method="getUserBeanService" />

aop面向切面编程

可以应用于分布在多个方法中的应用

可以作日志、可以做事务、可以做审计

可以用动态代理实现

在项目中怎么应用的?项目中主要应用于声明式事务

 //读取配置文件 

       ApplicationContext  =new ClassPathXmlApplicationContext("applicationContext.xml"); 

        //获取UserBean的实例 

       PersonBean bean=(PersonBean)ctx.getBean("userBean"); 

//调用方法

bean.show();

 Spring管理Bean的原理

Spring的配置文件中记录了类的包路径,因此我们首先是要读入配置文件。在配置文件中Bean有id和class两个属性。

Spring底层会去解析xml文件,并将里面的bean获取出来,封装到一个Map中,同时还提供了getBean这个方法。

解析XML的几种方式

(1)DOM解析
    (2)SAX(Simple API for XML)解析

(3)JDOM(Java-based Document Object Model)
    (4)DOM4J(Document Object Model for Java)
    (5)StAX(Streaming API for XML)

Dom

Dom是将整个xml文档以树型结构加载到内存中,可以进行crud操作

Sax
sax它是读取一行,解析一行,只能做查询操作

 

默认情况下,Spring的Ioc容器启动时会初始化bean,但是我们可以指定Bean节点的lazy-init="true",来延迟初始化bean。这时候,只有第一次获取bean才会初始化bean。

依赖注入的简单实现

-----------------------------------------

Spring的核心机制是依赖注入。依赖注入让bean与bean之间以配置文件组织在一起,而不是以硬编码的方式耦合在一起。依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。不管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。

注解注入 

如果使用前面的两种方法,配置文件将会显得很臃肿,因此我们可以使用注解的方式注入,使用注解方式注入有两种方法,

第一种使用javax.annotation.Resource中提供的注解方式方法如下:

@Resource默认是按照名称装配,找不到与名称匹配的bean时按类型装配

第二中方式就是使用spring提供的注解方式

org.springframework.beans.factory.annotation.Autowired;

 @Autowired默认使用类型进行装配,

在使用时建议使用@Resource,因为@Resource不依赖于spring框架。

Spring自动扫描和管理Bean

-------------------------------------------------

在前面的例子中,都是使用XML的bean定义来使用组件,在大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会使配置文件显得很臃肿,查找和维护起来不方便。

Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标记了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入到spring容器中管理,它的作用和在xml中使用bean节点配置组件一样。要使用自动扫描机制,我们需要把配置文件如下配置:

 

   <context:component-scan base-package="com.szy.spring"></context:component-scan> 

其中base-package为需要扫描的包(包括子包)

@Service用于标注业务层的组件,@Controller用于标注控制层组件(如struts中的action),@Repository用于标注数据访问组件,即DAO组件,而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。但是在目前的spring版本中,这几个注解的作用是一样的,但是在以后可能会进行区分。

 

静态代理和动态代理模式

代理模式分为静态代理和动态代理。

静态代理就是我们自己定义的代理类,动态代理是程序在运行时生成的代理类。

实现原理:代理类和目标对象实现同一个接口,代理类持有目标对象的引用。

代理对象其实就是隔在目标对象和调用者中间的一扇门。

 

动态代理

动态代理它可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在。

动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。

动态代理生成技术:

1.jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象。实现接口。

2.cglib  (spring学习)继承父类。

反射原理:

在理解反射的时候,不得不说一下内存。

先理解一下JVM的三个区:堆区,栈区,和方法去(静态区)。

堆区:存放所有的对象,每个对象都有一个与其对应的class信息。在JVM中只有一个堆区,堆区被所有的线程共享。

栈区:存放所有基础数据类型的对象和所有自定义对象的引用,每个线程包含一个栈区。每个栈区中的数据都是私有的,其他栈不能访问。

栈分为三部分:

基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

方法区:即静态区,被所有的线程共享。方法区包含所有的class和static变量。它们都是唯一的。

在启动一个java虚拟机时,虚拟机要加载你程序里所用到的类 ,这个进程会首先跑到jdk中(在jdk的jre/lib/ext文件夹里找那些jar文件),如果没有找到,会去classpath里设置的路径去找。

在找到要执行的类时:

1.首先将找到的类的信息加载到运行时数据区的方法区。这个过程叫做类的加载。所以一下static类型的在类的加载过程中就已经放到了方法区。所以不用实例化就能用一个static类型的方法。

2.加载完成后,在new一个类时,首先就是去方法区看看有没有这个类的信息。如果没有这个类的信息,先装载这个类。then,加载完成后,会在堆区为 new的这个类分配内存,有了内存就有了实例,而这个实例指向的是方法区的该类信息。其实就是存放了在方法区的地址。而反射就是利用了这一点。