spring基础

spring基础
1,软件应用分层架构
标准三层架构:
1:数据访问层:主要是对原始数据(数据库或者文本文件等存放数据的形式)的操作层,而不是指原始数据,也就是说,是对数据的操作,而不是数据库,具体为业务逻辑层或表示层提供数据服务。
2:业务逻辑层:主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理,如果说数据层是积木,那逻辑层就是对这些积木的搭建具体的讲主要负责对数据层的操作。也就是说把一些数据层的操作进行组合。
3:表示层:主要表示WEB方式,如果逻辑层相当强大和完善,无论表现层如何定义和更改,逻辑层都能完善地提供服务主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。


优点:
1:开发人员可以只关注整个结构中的其中某一层;
2:可以很容易的用新的实现来替换原有层次的实现;
3:可以降低层与层之间的依赖;
4:有利于标准化;
5:利于各层逻辑的复用。
6:结构更加的明确
7:在后期维护的时候,地极大降低了维护成本状语从句:维护时间
缺点:
1:降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如现在却必须通过中间层来完成。
2:有时会导致级联的修改这种修改尤其体现在自上而下的方向如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
3:增加了开发成本


Spring相关概念
1:轻量级的容器:
容器:弹簧容器帮我们管理业务逻辑层,里边有很多业务逻辑对象,有对象就有对象的生命周期的管理(创建,销毁)豆可复用的组件(反复使用,随意搭配),弹簧容器中都是豆组件。
轻量级:?容器给予的业务逻辑对象多少种服务春季给用户提供的服务完全有用户自己决定,春天想用什么服务自己开启使用但是重量级的都是只要你用就把所有的服务都给你,不能自己定制。
春天容器从来不能独立运行,一定借助于其他容器启动,或者借助网络容器启动,或者EJB容器启动。
特点:
应用模块之间耦合度小,组件都是可重用的,都是各自打包的


为什么春天?控制反转和依赖注入
1)动态解藕,方便开发,面向接口设计
通过弹簧提供的的IoC容器,我们可以将对象之间的依赖关系交由春天进行控制,避免硬编码所造成的过度程序耦合。有了春季,用户不必再为单实例模式类,属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用
2)方便程序的测试TDD(Test-Driven Development)
可以用非容器依赖的编程方式进行几乎所有的测试工作,在春天里,测试不再是昂贵的操作,而是随手可做的事情。
3)降低Java EE API的使用难度
Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个简单的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。
4)方便集成各种优秀框架
春天不排斥各种优秀的开源框架,相反,春天可以降低各种框架的使用难度,春天提供了对各种优秀框架(如Struts中,休眠,黑森州,石英)等的直接支持。
5)AOP编程的支持
通过弹簧提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
6)声明式事务的支持
在春天中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
7)对异常的处理方式,所有的都转换成未选中的。
8)它不是一个一体化的解决方案。
9)良好的设计,容易扩展,很多可重用的组件

春核心宗旨:简化企业级应用开发,同时给复杂问题提供强大的,非侵入性解决方案

Spring核心组件
(1),Spring Core(IOC)核心(3)Spring Web容器,web应用上下文,是webApplicationContext接口的实现(4

)弹簧容器,提供组件的创建,装备,销毁(2),弹簧语境上下文,是一个接口的ApplicationContext(继承自Bean工厂接口)的实现),弹簧DAO容器,是SpringDAO支持模块,是为了简化DAO的使用( 5,Spring ORM  (6),Spring AOP,对AOP编程支持的模块(7),Spring MVC,类似于Spring表示层的一个框架4,spring ioc(must):IOC:控制反转控制反转       一种说法:对象之间的依赖关系,容器由在运行时依据配置文件动态的建立       另一种说法:对象的控制器转移了,转到外部容器了,避免了代码的纠缠,代码更容易被维护,模板之间的耦合性降,测试容易的IoC的控制反转意味着将你设计好的类交给容器去控制,而不是在类的内部进行控制,即控制权由应用代码中转到了外部容器   

IOC:包括两部分内容

      DI:依赖注入依赖注入,组件不做定位查询,只提供相应方法,由容器创建对象,并调用相应方法设置所需对象需要的组件

      (不要求)DL:Dependency Loopup依赖查找,容器创建对象并提供回调接口和上下文环境给组件,需要时通过接口从容器中查找对象
依赖查找,现在使用不太多。(EJB使用的更多,将对象创建好后,放到容器中。)

国际奥委会解决:对象谁来创建的问题
DI解决:对象间的关系如何建立的问题。org.springframework.beans
 及org.springframework.context包是IOC容器的基础
SpringIOC核心api
BeanFactory接口和容器
   BeanFactory是Spring中Bean容器,IoC的核心接口,主要用于处理Bean的初始化和配置,建立对象间的依赖关系
   定义了如下方法:
   Object getBean(String name)//根据指定名称返回一个Bean实例


   <T> T getBean(Class <T> requiredType)  
                              //返回一个与给定类别唯一匹配的豆实例


   <T>Ť的getBean(字符串名称,类<T> requiredType)


   对象的getBean(字符串名称,对象...参数)


   类<?>的getType(字符串名称)//得到名称为name的Bean的类对象
   
   boolean isPrototype(String name)//判断名称为name的Bean是否是原型,
                                          即是否总是返回一个新实例
   boolean isSingleton(String name)//判断名称为name的Bean是否是单例


   boolean containsBean(String name)//判断是否包含给定名称的Bean实例


   boolean isTypeMatch(String name,Class <?> targetType)
                         //判断名称为name的Bean实例是否为targetType类型
   String [] getAliases(String name)//如果名称为name的Bean有别名返回
   
   通过getBean方法可以得到相应的类实例,但是最好永远不调用,而使用注入,
   避免对Spring API的依赖
   
   在Spring中,同一Spring容器中的bean默认情况下是Singleton(单例),将在bean
   的作用域介绍中。


ApplicationContext的接口
   该接口继承于Bean工厂,增强了BeanFactory中,提供了事务处理AOP,国际化,事件传递


所以在代码中我们一般会使用的ApplicationContext接口,以及这个接口相应的实现类来创建春天的容器对象。
例如:
String path =“com / briup / ioc / set / set.xml”;
ApplicationContext container = new ClassPathXmlApplicationContext(path);

配置文件
Spring通过读取配置文件中的数据来对应应用中的各个对象进行实例化,配置以及组装,通常使用XML文件来作为配置文件
   XML基本结构如下:
<?xml version =“1.0”encoding =“UTF-8”?>
<beans xmlns =“http://www.springframework.org/schema/beans”
的xmlns:的xsi = “http://www.w3.org/2001/XMLSchema-instance”
的xmlns:上下文= “http://www.springframework.org/schema/context”
的xsi:的schemaLocation =“http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.2.xsd“>
   
</豆>


   这个文件的头部声明可以在下载的弹簧文档中的示例找到。注意这里面用到了俩个模式文件(的.xsd文件),就是弹簧豆-3.2.xsd和弹簧上下文3.2的.xsd,这俩个文件在下载的弹簧文档中也是可以找到的。我们在Eclipse的中把XML文件和模式文件关联(注意上课的演示步骤)后,在这个XML中就可以有智能提示了。还有一点需要注意,将来我们这XML中再引入另外的模式文件后在配置的时候就可以智能提示出新的配置内容,春天是又很多模块组成的,我们需要什么功能的配置标签就需要引入对应的模式文件,从而获得智能提示,同时也能帮我们验证配置的正确性

IOC注入
1)set方式注入(必须依靠set方法)
   可以注入的内容有:
      A,基本类型(8中基本类型+字符串)的装配
      B,对象类型的装配
      C,集合的装配

   A,基本类型的装配
      方式:配置元素<value />
      例子:
公共类HelloBean {
私人字符串名称;
私人年龄;
public String sayHello(){
返回“你好”+姓名+“,你的年龄是”+年龄;
}
.............
}
配置文件set.xml
<bean id =“helloBean”class =“ioc.HelloBean”>
<property name =“name”>
<值>汤姆</值>
</属性>
<property name =“age”value =“20”>
</属性>
</豆>
<! -
ID是豆的唯一标识,要求在整个配置文件中要唯一,也可使用名称属性,豆标签里面的ID和名字属性都可以用来标识这个配置的对象,但是ID会帮我们检查给对象起的名字是否规范(名字不能重复,不能用数字开头,不能有空格等等),如果检查出来了那么就会报错。名称属性不会帮检查这些东西。
- >
<! - property对于所有用set方式来注入的必须改标签 - >
<! - value是对以基本类型,都用value(标签/属性)来注入,可以实现自动的数据类型转换 - >

测试类:
   主要:
ApplicationContext ac = 
新的ClassPathXmlApplicationContext(“set.xml”);
//获取容器的一个实例
HelloBean hb =(HelloBean)ac.getBean(“helloBean”);

的的System.out.println(hb.sayHello());


   B,对象类型的装配
  (1),<ref local =“”/>用于涉及的对象的id在本配置文件中
  (2),<ref bean =“”/>用于涉及的对象的id不在本配置文件中
  (3),使用属性的REF属性引用


公共类OtherBean {
私人字符串str1;
public String getStr1(){
返回str1;
}
public void setStr1(String str1){
this.str1 = str1;
}
public String toString(){
返回“OtherBean”+ str1;
}
}


公共类SomeBean {
私人的OtherBean ob;
public void printInfo(){
System.out.println(“someBean”+ ob);
}
public OtherBean getOb(){
回报
}
public void setOb(OtherBean ob){
this.ob = ob;
}
}


配置applicationContext.xml中
<bean id =“someBean”class =“ioc.SomeBean”>
<property name =“ob”>
<ref bean =“otherBean”/>
</属性>
</豆>
配置other.xml文件
<bean id =“otherBean”class =“ioc.OtherBean”>
<property name =“str1”>
<值>字符串1 </值>
</属性>
</豆>


测试类:
主要:
String [] path = {“ioc / applicationContext.xml”,“ioc / other.xml”};
ApplicationContext ac = new ClassPathXmlApplicationContext(path);
SomeBean sb =(SomeBean)ac.getBean(“someBean”);
sb.printInfo();


知识点1:
spring容器怎么管理我们配置的对象:
默认情况下,spring容器用单例的模式来管理这些对象。通过相同的一个对象名字,多次在容器中拿对象,每一次拿到的都是相同的对象(单例)

通过配置,我们可以让spring容器使用非单例的模式来管理这个对象。 通过相同的一个对象名字,多次在容器中拿对象,每一次拿到的都是不同的对象(非单例)在bean标签中加入属性scope =“prototype”


知识点2:
<bean name =“teacher”class =“...”> 
命名属性的值是自己随便起的
类属性的值表示这里要配置的是哪一个类的对象

<property name =“student”ref =“student”>
命名属性的值表示一个方法,这里表示的是setStudent方法
REF属性表示调用这个setStudent方法的时候要用的参数是名字为学生对象的


知识点3:
 可以给某一个对象起一个别名: 
 这个时候,不管用学生还是用S1,俩这个名字个都是
 指向的同一个学生类型的对象
 <bean name =“student”class =“com.briup.bean.Student”> </ bean>
 <alias name =“student”alias =“s1”/>

知识点4:
可以给一个类配置多个对象,的对象名字要不同 

知识点5:
豆标签里面的ID和名字属性都可以用来标识这个配置的对象
 但是ID会帮我们检查给对象起的名字是否规范
 (名字不能重复,不能用数字开头,不能有空格等等),
 如果检查出来了那么就会报错。
 名称属性不会帮检查这些东西

C,集合的装配
方式:配置元素<list> <set> <map> <props>
公共类SomeBean {
私人列表listProperty;
私人设置setProperty;
私人地图地图物业;
私有属性<String,String>属性;
public List getListProperty(){
返回listProperty;
}
public void setListProperty(List listProperty){
this.listProperty = listProperty;
}
public Set getSetProperty(){
返回setProperty;
}
public void setSetProperty(Set setProperty){
this.setProperty = setProperty;
}
public Map getMapProperty(){
返回mapProperty;
}
public void setMapProperty(Map mapProperty){
this.mapProperty = mapProperty;
}
公共属性getProperty(){
归还财产;
}
public void setProperty(Properties property){
this.property =属性;
}
public void printInfo(){
的System.out.println( “的ListProperty”);
的System.out.println(的ListProperty);
的System.out.println( “的setProperty”);
的System.out.println(的setProperty);
Set set = mapProperty.entrySet();
Iterator it = set.iterator();
而(it.hasNext()){
Map.Entry entry =(Entry)it.next();
System.out.println(“Key”+ entry.getKey());
System.out.println(“value”+ entry.getValue());
}
System.out.println(“props:”);
Set set2 = property.entrySet();
Iterator it2 = set2.iterator();
而(it2.hasNext()){
Map.Entry entry =(Entry)it2.next();
System.out.println(“key”+ entry.getKey());
System.out.println(“value”+ entry.getValue());
}
}
}


applcationContext.xml的写法:
<bean id =“someBean”class =“ioc.SomeBean”>
<property name =“listProperty”>
<列表>
    <值> list1的</值>
    <值> list1的</值>
    <值>项目list3 </值>
</列表>
</属性>
<property name =“setProperty”>
<设置>
    <值> SET1 </值>
    <值> SET1 </值>
    <值> SET3 </值>
</设定>
</属性>
<property name =“mapProperty”>
<地图>
    <entry key =“key1”>
  <值>值1 </值>
    </条目>
    <entry key =“key2”>
  <值>值2 </值>
    </条目>
</地图>
</属性>
<property name =“property”>
     <道具>
  <prop key =“key1”> prop1 </ prop>
  <prop key =“key2”> prop2 </ prop>
  <prop key =“key3”> prop3 </ prop>
     </道具>
</属性>
</豆>


测试类:
主要:
String path =“ioc / applicationContext.xml”;
ApplicationContext ac =
新的ClassPathXmlApplicationContext(路径);
SomeBean sb =(SomeBean)ac.getBean(“someBean”);
sb.printInfo();

2)基于构造器注入
方式:配置<constructor-arg>元素
在豆中不用写一套方法,但是要有相应的构造器

构造器注入有俩种形式一个是根据参数类型一个是根据参数位置的下标
<constructor-arg type =“int”value =“”>
<constructor-arg index =“0”value =“”>
例如:
<bean name =“student”class =“com.briup.bean.Student”>
    <constructor-arg type =“int”value =“25”>
    </构造精氨酸>
   
    <constructor-arg type =“java.lang.String”value =“tom”>
    </构造精氨酸>
   
    <constructor-arg type =“long”value =“100”>
    </构造精氨酸>
     
</豆>

或者:
<bean name =“student”class =“com.briup.bean.Student”>
<constructor-arg index =“2”>
<值> 30 </值>
</构造精氨酸>
 
<constructor-arg index =“0”>
<值> 200 </值>
</构造精氨酸>
 
<constructor-arg index =“1”>
<值>百合</值>
</构造精氨酸>
</豆>

3)自动注入:容器依照一些规则去装配豆的中一个属性
      注意:自动装配只对[对象类型]起作用,对基本类型不起作用。
      第一种情况:
      在豆类标签中配置装载方式:default-autowire =“byName”
      default-autowire =“byName”
    在根元素豆中加入这个属性,那么下面所有的bean的都会
    使用绰号的方式进行自动注入,如果在下面的某一个豆
    里面想使用其他的方式进行注入,可以用自动装配= “” 属性进行
    说明,或者某一个豆不想使用任何自动注入就使用自动装配= “否”


      第二种情况:
      在豆标签中指定配置方式
      自动装配= “绰号”:
    春天容器会到当前的类中找物业的名字,然后
    再根据这个名字去春容器中找有没有和这个财产
    名字相同的对象,有的话,就把这个对象当做参数放到
    的setXXXX这个方法里面注入进来。
    注意:了解property指的类中的什么东西


      。autowire =“byType”:
    春天容器会根据当前类中的设置方法里面参数的类型,
    去容器中找相匹配的对象,如果没找到就算了,如果找到
    一个就注入进来,如果找到多个,那么就会报错了。


      autoWrite = “构造” 
根据构造器的参数类型去匹配




4)继承:并不是oo的继承关系
      bean的定义的继承,指定bean的配置可去继承
                  | --true抽象化代码中不能getBean获取其对象
      abstract = - |
                  | --false默认


      parent =“父类bean的id /名称”


      例子:
<bean name =“student”class =“com.briup.bean.Student”>
<property name =“name”>
<值>张三</值>
</属性>
</豆>


<! - 
abstract =“true”表示当前的配置是一个抽象的配置,
这时候我们在代码中就不能通过这个豆的名字的老师来
获得相应的对象了(和java的中的抽象类不能直接新对象的道理一样)

但是我们可以在写一个配置去继承这个抽象的配置,当然即使当前
这个配置不是抽象的,也能够被继承(和java的中继承一样)
- >


<bean name =“teacher”class =“com.briup.bean.Teacher”abstract =“true”>
<property name =“student”ref =“student”> </ property>
</豆>


<! - 
parent =“teacher”表示当前配置是继承了另外一个名字叫
老师的豆的配置,配置和配置的继承像Java的中的类和类
直接的继承一样,子类会把父类中的对象继承过来。
当然在子配置里面依然是可以覆盖父配置中已经写的配置信息。
- >


<bean name =“t”parent =“teacher”>

<property name =“id”>
<值> 11 </值>
</属性>


<property name =“name”>
<值> TeacherWang </值>
</属性>
</ bean>

bean对象的生命周期(了解)

生命周期执行的过程如下(不用记,作为了解即可):

1)spring对豆进行实例化,默认豆是单例
2)spring对豆进行依赖注入
3)如果豆实现了BeanNameAware接口,弹簧将豆的ID传给setBeanName()方法
4)如果豆实现了了BeanFactoryAware接口,弹簧将调用setBeanFactory方法,将BeanFactory的实例传进来
5)如果豆实现了了ApplicationContextAware()接口,弹簧将调用setApplicationContext()方法将应用上下文的引用传入
6)如果bean实现了BeanPostProcessor接口,spring将调用它们的postProcessBeforeInitialization接口方法
7)如果bean实现了InitializingBean接口,spring将调用它们的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,改方法也会被调用
8)如果豆实现了BeanPostProcessor的接口,弹簧将调用它们的postProcessAfterInitialization接口方法
9)此时豆已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁
10)若豆实现了DisposableBean的接口,弹簧将调用它的distroy()接口方法。同样的,如果豆使用了破坏法属性声明了销毁方法,则该方法被调用
其实很多时候我们并不会真的去实现上面说描述的那些接口,那么下面我们就除去那些接口针对豆的单例和非单例来描述下豆的生命周期:

单例管理的对象:
1.默认情况下,spring在读取XML文件的时候,就会创建对象。
2.在创建的对象的时候(先调用构造器),会去调用初始化方法= “..”
属性值中所指定的方法。
3.对象在被销毁的时候,会调用破坏法= “...” 属性值中
所指定的方法。(例如调用container.destroy()方法的时候)
4.lazy-INIT = “真”,可以让这个对象在第一次被访问的时候创建

非单例管理的对象:在豆标签上追加范围= “原型”
1.spring读取XML文件的时候,不会创建对象。
2.在每一次访问这个对象的时候,spring容器都会创建这个对象,并且
调用初始化方法= “..” 属性值中所指定的方法。
3.对象销毁的时候,spring容器不会帮我们调用任何方法,
因为是非单例,这个类型的对象有很多个,spring容器一旦把
这个对象交给你之后,就不再管理这个对象了。


注意:一个单例管理的对象中,注入了非单例管理的对象的情况。 
<! - 
   <bean name =“life”
    class =“com.briup.bean.LifeBean” 
    init-method =“init”
    destroy-method =“destory” 
    lazy-init =“true”> </ bean>
- >
<bean name =“life” 
    class =“com.briup.bean.LifeBean”
    scope =“prototype” 
    init-method =“init”> </ bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值