spring之路

来源:互联网 发布:mac迅雷怎么看片 编辑:程序博客网 时间:2024/05/31 05:28
spring是什么
          struts2是web框架(jsp/action)(struts2充当web,接管jsp/action/表单 主要体现出mvc的数据输入、数据的处理,数据的显示分离)
          hibernate是orm框架,处于持久层
          spring是容器框架,用于配置bean,并维护bean之间关系的框架
          <spring中有一个非常概念:bean(是java中的任何一种对象  可以是javabean/service/action/数据源/dao),ioc(控制反转 inverse of control) di(dependency injection 依赖注入)>
      
model层(业务层+dao层+持久层  一个项目中不一定同时存在这些层,根据实际情况选择)

ApplicationContext是重量型的,因此要把它做成一个单态的

di配合接口编程 ,可以减少层(web层)和层(业务层)的耦合度

开发一个spring项目:
1>引入spring的开发包(最小配置  spring.jar  该包把常用的jar都包括,还要写日志包common-logging.jar)
2>创建spring的一个核心文件applicationContext.xml,【hibernate有核心  hibernate.cfg.xml
                               struts核心文件  struts-config.xml】,还文件一般放在src目录下,该文件
                              中引入xsd文件,可以从给出的案例中拷贝一份
3>配置bean       bean元素的作用是:当我们spring框架加载时候,spring就会自动的创建一个bean对象,并放入内存管理起来
                              (bean中的id就类似于该bean对象的引用  class就直接指向一个类)
                              <bean id="userService" class="com.service.UserService">
                                   <property name="name">
                                             <value>林</value>
                                   </property>
                              </bean>
                              将name属性以及值注入bean(属性必须在指向类里面定义好setter方法)

                         //实例化spring容器对象,然后通过该对象获取bean对象
             ApplicationContextac=newClassPathXmlApplicationContext("applicationContext.xml");
             UserServiceus=(UserService)ac.getBean("userService");
             us.sayHello();
             
ioc是什么?
答:ioc控制反转:控制反转就是把创建对象(bean),和维护对象(bean)的关系的权利从程序中转移到spring的容器
     (applicationContext.xml)

两种方式获取bean的区别:
使用上下文的方式     当我们去实例化beans.xml,该文件中配置的bean被实例(无论该bean有没有被获取并且该bean的scope是singleton的时候)
从bean工厂方式       当bean被调用时才被实例  
BeanFactoryfactory=newXmlBeanFactory(newClassPathResource("com/hsp/ioc/beans.xml"));
总结:如果使用ApplicationContext,则配置的bean如果是singleton不管你用不用,都被实例化(好处就是可以预先加载,缺点就是耗内存)
          如果是BeanFactory,则你实例化该对象时候,配置的bean不会马上实例化,当你使用的时候才被实例(好处节约内存,缺点就是速度)
          一般没有特殊要求,应当使用ApplicationContext完成(90%)

三种获取ApplicationContext 对象引用的方式
1>ClassPathXmlApplicationContext->通过类路径     (桌面应用比较多用)
2>FileSystemXmlApplicationContext->通过文件路径
ApplicationContext  ac=newFileSystemXmlApplicationContext("C:\\Users\\lin\\Workspaces\\MyEclipse 2015\\spring1\\src\\com\\hsp\\ioc\\beans.xml");
3>XmlWebApplicationContext     (当Tomcat启动时会自动加载)

bean的生命周期
1>实例化(当我们的程序加载beans.xml),把我们的bean(前提是scope=singleton)实例化到内存
2>调到set方法设置属性
3>如果你实现了bean名字关注接口(BeanNameAware),则可以通过setBeanName获取id号
4>如果你实现了bean工厂关注接口,(BeanFactoryAware),则可以获取BeanFactory
5>如果你实现了ApplicationContextAware接口,则调用方法
     //该方法传递ApplicationContext
     public void setApplicationContext(ApplicationContext arg0) throws BeansException{
          System.out.println("ApplicationContext  "+arg0);
     }
6>如果bean和一个后置处理器关联,则会自动去调用     ObjectpostProcessBeforeInitialization方法
7>如果你实现InitializingBean接口,则会调用afterPropertiesSet
8>如果自己在<bean init-method="init"/>  则可以在bean定义自己的初始化方法
9>如果bean和一个后置处理器关联,则会自动去调用  Object postProcessAfterInitialization方法
10>使用我们的bean
11>容器关闭
12>可以通过实现DisposableBean  接口来调用方法destory
13>可以在<bean destory-method="fun1"/>  调用定制的销毁方法

小结:实际开发中常见的过程是  1>2>6>10>9>11

装配Bean
基本装配:在spring容器内拼凑bean叫装配。装配bean的时候,需要告诉容器哪些bean以及容器如何使用依赖注入将它们配合在一起

使用XML装配:xml是最常见的spring应用系统配置源
几种spring容器都支持xml装配bean,包括:
1>XmlBeanFactory:调用CalssPathResource载入上下文
2>ClassPathXmlApplicationContext:从类路径载入上下文定义文件
3>XmlWebApplicationContext:从web应用上下文中载入定义文件

通过set方法注入依赖
<bean>元素的<property>子元素指明了使用它们的set方法来注入。可以注入任何东西,从基本类型到集合类,甚至是应用系统的bean

java中主要的集合有几种:map set list/数组

数组注入:
<propertyname="empName">
       <list>
             <value>小明</value>
             <value>大明</value>
             <value>大大明</value>
       </list>
</property>

list注入:
<propertyname="empList">
       <list>
             <refbean="emp1"/>
             <refbean="emp2"/>
       </list>
</property>
</bean>
<beanid="emp1"class="com.hsp.collection.Employee">
<propertyname="name"value="北京"/>
</bean>
<beanid="emp2"class="com.hsp.collection.Employee">
<propertyname="name"value="天津"/>
</bean>

set注入值,set不能有相同的对象
<property name="empsets">
     <set>
          <ref bean="emp1"/>
          <ref bean="emp2"/>
     </set>
</property>

 map注入
<property name="empsets">
     <map>
         <entry key="11" value-ref="emp1"/>
         <entry key="22" value-ref="emp2"/>
     </map>
</property>


内部bean(可以和引用bean递归使用)
<bean id="foo" class="...Foo">
     <property name="bar">
          <bean name="...Bar">
     </property>
</bean>

基本装配:
1>继承
2>继承配置
3>覆盖父bean配置
4>可以设置<bean>的abstract属性为true,spring不会实例化该bean

<bean id="gradate" parent="student" class="...Gradate">

<beanid="student"class="com.hsp.inherit.Student">
       <propertyname="name"value="冰玉"/>
       <propertyname="age"value="18"/>
</bean>
<beanid="gradate"parent="student"class="com.hsp.inherit.Gradate">
       <propertyname="degree"value="学士"/>
       <propertyname="name"value="刘冰玉"/>
       <propertyname="age"value="118"/>
</bean>

给属性集合配置
<property  name="pp">
     <pros>
          <prop key="pp1">abcd</prop>
          <prop key="pp2">hello</prop>
     </pros>
</property>

给属性注入空值
<property name="barlis">
     <null/>
</property>


通过构造函数注入值

beans.xml关键代码
<beanid="employee"class="com.hsp.constructor.Employee">
<constructor-argindex="0"type="java.lang.String"value="大明"/>
<constructor-argindex="1"type="int"value="23"/>
</bean>

会根据属性个数调用对应的构造函数

set注入和构造函数注入对比:
set注入的缺点是无法清晰表达哪些属性是必须的,哪些是可选的,构造注入的优势是通过构造强制依赖关系,不可能实例化不完全的或无法使用的bean

自动装配bean的属性值
1、byName(根据属性名自动装配,若找不到,则装不上)

<beanid="dog"class="com.hsp.autowire.Dog">
<propertyname="name"value="小黄"/>
<propertyname="age"value="3"></property>
</bean>
       
                    
<beanid="master"class="com.hsp.autowire.Master"autowire="byName">
<propertyname="name">
<value></value>
</property>
</bean>

2、byType:寻找和属性类型相同的bean,找不到则装不上,找到多个抛出异常
<beanid="dog11"class="com.hsp.autowire.Dog">
<propertyname="name"value="小黄"/>
<propertyname="age"value="3"></property>
</bean>
       
       
             
<beanid="master"class="com.hsp.autowire.Master"autowire="byType">
<propertyname="name">
<value></value>
</property>
</bean>

3、constructor:查找和bean的构造参数一致的一个或哆哥bean,若找不到或找到多个,抛异常。按照参数的类型装配

4、autodetect:(3)和(2)之间选一个方式。不确定性的 处理与(3)和(2)一致

5、default:这个需要在<beans default-autowire="指定"/>

6、no:不自动装配,这是autowrite的默认值


AOP编程:对有所对象或者是一类对象编程,核心是(在不增加代码的基础上,还增加功能)

步骤:
1>定义接口
2>编写对象(被代理对象=目标对象)
3>编写通知(前置通知目标方法调用前调用)
4>在beans.xml文件配置
4.1>配置被代理对象=目标对象
4.2>配置通知
4.3>配置代理对象  ProxyFactoryBean的实例
     4.3.1>配置代理接口集
     4.3.2>织入通知
     4.3.3>配置被代理对象

spring的aop中,当你通过代理对象去实现aop的时候,获取的 ProxyFactoryBean是什么类型?
答:返回的是一个代理对象,如果 目标对象实现了接口,则spring使用jdk动态代理技术;如果目标对象没有实现接口,则spring使用CGLIB技术

ssh整合
1>先搞定Spring
2>引入Spring开发包
3>编写beans.xml文件,并把该文件放在src目录下
4>测试一下spring是否ok->编写一个javabean并把它配置在spring的bean中,然后通过实例化容器并且获取该bean和打印bean内容,若成功,则ok
5>加入hibernate开发包
6>因为我们是ssh2,所以hibernate的核心就被spring接管了hibernate.cfg.xml文件对象映射文件,SessionFactory在spring的文件中配置即可
7>在applicationContext.xml中配置数据源
<!-- 配置数据源 -->
<beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
          <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
          <propertyname="url"value="jdbc:mysql://localhost:3306/test"/>
          <propertyname="username"value="root"/>
          <propertyname="password"value="123456"/>
           <!-- 连接池启动时的初始值 -->
             <propertyname="initialSize"value="30"/>
              <!-- 连接池的最大值 -->
              <propertyname="maxActive"value="500"/>
             <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
             <propertyname="maxIdle"value="2"/>
             <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
             <propertyname="minIdle"value="1"/>
</bean>
8>配置SessionFactory对象
<!-- 配置会话工厂() -->
<beanid="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <!-- 设置数据源 -->
    <propertyname="dataSource"ref="dataSource"/>
    <!-- 接管了hibernate对象映射文件 -->
    <propertyname="mappingResources">
          <list>
            <value>lin/domain/Course.hbm.xml</value>
            <value>lin/domain/Department.hbm.xml</value>
            <value>lin/domain/Manager.hbm.xml</value>
            <value>lin/domain/Specialty.hbm.xml</value>
            <value>lin/domain/Student.hbm.xml</value>
            <value>lin/domain/Teacher.hbm.xml</value>
          </list>
    </property>
    <propertyname="hibernateProperties">
          <value>
                    hibernate.dialect=org.hibernate.dialect.MysqlDialect
                    hibernate.hbm2ddl.auto=update
                           hibernate.show_sql=true
                           hibernate.cache.use_second_level_cache=true
                 hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
                 hibernate.generate_statistics=true       
       </value>
   </property>
</bean>
9>我们编写domain对象和映射文件xxx.hbm.xml->测试spring和hibernaye是否可以结合使用->ok
10>考虑分层
11>使用事务管理器来统一管理事务
<!-- 配置事务管理器,统一管理sessionFactory的事务 -->
<beanid="txManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">
       <propertyname="sessionFactory"ref="sessionFactory"/>
</bean>

12>配置我们的二级缓存
<propertyname="hibernateProperties">
          <value>
                    hibernate.dialect=org.hibernate.dialect.MySQLDialect
                    hibernate.hbm2ddl.auto=update
                           hibernate.show_sql=true
                           hibernate.cache.use_second_level_cache=true
                 hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
                 hibernate.generate_statistics=true       
       </value>
</property>
1 0
原创粉丝点击