spring--入门

一、Spring基本特征


1.Spring是一个非常活跃的开源框架;它是一个基于Core来构架多层JavaEE系统的框架,它的主要目地是简化企业开发. 

  2.Spring的 jar包

3.Spring配置文件
      默认情况下是applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
Spring IOC(控制反转)
 <bean id="person" class="com.itheima12.spring.di.xml.setter.Person">
依赖注入(DI)
<!--  利用对应的构造函数构造对象(默认调用无参的构造函数)-->
<constructor-arg index="0">
      <value>张三</value>
</constructor-arg>
    <!-- property就是一个bean的属性、name就是用来描述属性的名称value就是值、如果是一般类型(基本类型和String)-->
    <property name="pid" value="1"></property>
    <property name="name" value="狗蛋"></property>
    <!-- spring容器内部创建的student对象给Person的student对象赋值了-->
    <property name="student">
    <ref bean="student"/>
    </property>
    <property name="lists">
    <list>
    <value>list1</value>
    <value>list2</value>
    <ref bean="student"/>
    </list>
    </property>
    <property name="sets">
    <set>
    <value>set1</value>
    <value>set2</value>
    <ref bean="student"/>
    </set>
    </property>
    <property name="map">
    <map>
    <entry key="m1">
    <value>map1</value>
    </entry>
    <entry key="m2">
    <ref bean="student"/>
    </entry>
    </map>
    </property>
    <property name="properties">
    <props>
    <prop key="p1">prop1</prop>
    <prop key="p2">prop2</prop>
    </props>
    </property>
    <property name="objects"><!-- 对应Object[]数组-->
    <list>
    <value>obj1</value>
    <ref bean="student"/>
    </list>
    </property>
   </bean>
</beans>


4.Spring基本功能详解
SpringIOC
Spring的控制反转:把对象的创建、初始化、销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。


   A.启动spring容器
1、在类路径下寻找配置文件来实例化容器 
                     ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");可以在整个类路径中寻找xml文件


   B.从spring容器中提取对象
3.2别名
<beans>
<alias name="person" alias="p"/>
<bean name="person" class="cn.itcast.aliasspring.Person"/>
</beans>


   C.Spring容器内部对象
 
   创建对象的方式:
a.无参构造函数
<bean id=“personService" class="cn.itcast.bean.impl.PersonServiceImpl"/>
b.静态工厂
<bean id="personService"  class="com.itcast.factory.PersonServiceFactory"    factory-method="createPersonService" />
c.实例工厂
<bean id="personServiceFactory" class="com.itcast.factory.PersonServiceFactory"></bean>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createPersonService"></bean>


   D.对象的scope
* singleton/default(默认)
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。


* prototype 允许bean可以被多次实例化(使用一次就创建一个实例) . 
* Request  在一次HTTP请求中,一个bean定义对应一个实例,该作用域仅在基于web的spring ApplicationContext情形下有效。
* Session 在一次HTTP Session中,一个bean定义对应一个实例,该作用域仅在基于web的spring ApplicationContext情形下有效。
* Global session 在一个全局的Http Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。
该作用域仅在基于web的spring ApplicationContext情形下有效。


   E.init、destroy(初始化方法可以获取Hibernate的this.getHibernateTemplate.getSessionFactory)***********************************


<bean id=“foo” class=“...Foo”init-method=“setup” destory-method=“teardown”/>
当foo被载入到Spring容器中时在构建对象之后(调用无参构造函数)如果有属性的装配先调用属性的Set方法之后调用init-method方法。
当foo从容器中删除时调用destory-method(scope = singleton有效)


   F.注解
A.在配置文件中,引入context命名的名称空间
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"


B.在配置文件中加入context:annotation-config标签
<context:annotation-config/> 


   使用:@PostConstruct//Spring容器的初始化方法注解
@Resource(name="student")标注在字段或属性的setter方法上.(只适用于引用类型数据)javax.annotation.Resource
@Resource = @Autowired + @Qualifier
@Autowired  //按照类型进行匹配org.springframework.beans.factory.annotation.Autowired;
@Qualifier("student")//按照指定注解属性名进行匹配org.springframework.beans.factory.annotation.Qualifier;
原理:
1、当启动spring容器的时候,创建两个对象
2、当spring容器解析到<context:annotation-config></context:annotation-config>
  spring容器会在spring容器管理的bean的范围内查找这些类的属性上面是否加了@Resource注解
3、spring解析@Resource注解的name属性,
  如果name属性为"",说明该注解根本没有写name属性,spring容器会得到该注解所在的属性的名称和spring容器中的id做匹配,如果匹配成功,则赋值如果匹配不成功,则按照类型进行匹配
  如果name属性的值不为"",则按照name属性的值和spring的id做匹配,如果匹配成功,则赋值,不成功,则报错
@PostConstruct//指定Bean的初始化方法
@PreDestroy//指定Bean的销毁方法


G.扫描(与引入注解的名称空间一样)
spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Repository、@Service、@Controller注解的类
1.
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 配置自动扫描的标签(扫描cn.itcast包及子包)-->
<context:component-scan base-package="cn.itcast"/>
</beans>
2.在配置文件中添加context:component-scan标签 
        <context:component-scan base-package="cn.itcast"/>
 
3.功能介绍
@Repository用于标注数据访问组件,即DAO组件。
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)、
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。


F.spring中的继承
  如果父类中配置的参数子类需要继承下来用有两种方案:
1.在子类<bean id="" class="" parent="父类的id值">配上parent属性值即可
2.在子类调用父类的set方法进行属性的装配<bean id="" class=""><property name="" value=""></property></bean>


5.SpringAOP面向切面编程(需要导入面向切面编程的aspectj包、和CGLIB包)


a.JDK动态代理(基于接口的动态代理)java.lang.reflect.Proxy


public class JDKProxy implements InvocationHandler{
private Object target;


public Object createProxyInstance(Object target){
this.target = target;


return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
return method.invoke(this.target,args);//定义方法的返回值
}
}
           b.CGLIB做代理(基于子类的动态代理)   可以在Spring配置文件中设置<aop:config proxy-target-class="true"> 强行为CGLB代理
public class CGLIBProxy implements MethodInterceptor{  
private Object target;//代理目标类
public Object createProxyInstance(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();//生产代理对象
enhancer.setSuperclass(this.target.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return Enchancer.create();//创建代理对象
}  
public Object intercept(Object obj,Method method,Object[] args,MethodProxy methodProxy)throws Throwable{
return method.invoke(this.target,args);//定义方法的返回值
}
}        
**************************************************************AOP编程************************************************************************************************************
引入名称空间:
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd


* Aspect(切面)
比如说事务、权限等,与业务逻辑没有关系的部分的类(非目标对象)


* Pointcut(切入点)
所谓切入点是指我们要对那些拦截的方法的定义.(需要拦截的条件)


* joinpoint(连接点)
目标类的目标方法。(由客户端在调用的时候决定)


* Advice(通知)
所谓通知是指拦截到joinpoint之后所要做的事情就是通知.(执行切面的方法)
方法参数类型
通知分为前置通知 JoinPoint joinPoint
后置通知,JoinPoint joinPoint,Object value
异常通知,JoinPoint joinPoint,Throwable ex
最终通知,JoinPoint joinPoint
环绕通知 ProceedingJoinPoint joinPoint  //ProceedingJoinPoint的proceed方法相当于invoke方法,调用目标类的目标方法
joinPoint.getSignature().getName()//连接点名字
joinPoint.getTarget().class()//目标类


* Target(目标对象):
代理的目标对象


* Weaving(织入)
是指把切面应用到目标对象来创建新的代理对象的过程.切面在指定的连接点织入到目标对象 


 AOP实现的两种模式


XML形式:
<!--在spring配置文件中声明目标类-->
<bean id="service" class=""></bean>
<!--在spring配置文件中声明切面-->
<bean id="transaction" class=""></bean>
<!-- 定义AOP代理类 -->
<aop:config>
<!--id代表切入点的唯一 切入点表达式 确定代理目标-->
<aop:pointcut id="perform" expression="execution(* *(..))">
<!--  ref指向的对象就是切面(重点)-->
<aop:aspect ref="transaction">
<!-- 前置通知 在目标方法执行前执行(获取不到返回值)-->
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<!-- 后置通知 在目标方法执行后执行(可以获取返回值)-->
<aop:after-returning method="commit" pointcut-ref="perform" retrun="val"/>
<!--环绕通知 能控制目标方法的执行-->
<aop:around method="" pointcut-ref="perform">


<!-- 最终通知 无论目标方法是否抛出异常都将执行-->
<aop:after method="" pointcut-ref="perform">
<!--异常通知-->
<aop:after-throwing method="" pointcut-ref="perform" throwing="ex">
</aop:aspect>
</aop:config>


**************切入点中表达式方式:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern name-pattern (param-pattern) throws-pattern?)
修饰符 返回值类型  所在的包和类 方法名 参数 异常
execution(public * *(..))任意的公共方法
execution(* set*(..))以set开头的任意方法
execution(* com.service.AccountService.*(..)) com.service.AccountService类中的所有的方法
execution(* com.service.*.*(..))com.service包下的所有的类的所有的方法
execution(* com.service..*.*(..))com.service包及子包的所有的类的所有方法
execution(* com.*.service.*.*(..))com包下的任意一个包下的service包下的所有类的所有方法
execution(* com..service..*.*(..))com包及子包一直到service包及子包所有类的所有方法

AOP注解形式:
在Spring配置中启动使用@AspectJ切面的支持
<aop:aspectj-autoProxy/>


eg:
@Aspect//声明切面
public class TransactionManager{
//表示service包下所有以save开头的方法
    @Pointcut("execution(* com.service.*.save*(..))")
    private void aa(){} //方法签名 返回值必须为void


//前面定义的方法签名,参数必须与通知一样
    @Before("aa()&&args(userName,password)")
    public void beginTransaction(String userName,String password){}


//前面定义的方法签名,方法无返回值时为空
    @AfterReturning(pointcut="aa()",returning="value")
    public void commit(Object value){}


    @AfterThrowing(pointcut="aa()",throwing="ex")
    public void throwsEx(Exception ex){}


    @After("aa()")
    public void finalMessage(){}


    @Around("aa()")
    public Object aroundMessage(ProceedingJoinPoint point) throws Throwable{
String methodName = point.getSignature().getName();
String[] methodArgs = point.getArgs(); 
Class clazz = point.getTarget().getClass();
point.proceed();//调用目标对象的目标方法
    }
}


六、Spring数据库***************************************************************************************************************
JdbcAccessor-->JdbcTemplate-->JdbcDaoSupport
HibernateAccessor-->HibernateTemplate-->HibernateDaoSupport


**********Spring+JDBC(Hibernate类似)


Jdbc编程特点:静态代码+动态变量 = jdbc编程。


  1、在Spring配置中引入DataSource

   方式一:
  <!-- 引入jdbc.prperties配置文件-->
  <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<!-- 声明jdbc.properties文件在classpath路径下-->
<value>classpath:jdbc.properties</value>
</property>
</bean>
    
  <bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>


<!--******jdbc.properties配置内容(附件)*****-->
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://localhost\:3306/hibernate(自定义)
jdbc.username=root
jdbc.password=root
------------------------------------------------------------------------------------------------
   方式二:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDaraSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver">
    <property name="url" value="jdbc:mysql://localhost:3306/hibernate">
    <property name="username" value="root">
    <property name="password" value="root">
</bean>


   2、核心类JdbcTemplate
a.基于模板的设置(为什么可以设置成基于模板的形式)
b.完成了资源的创建和释放的工作
c.简化为我们对JDBC的操作
d.完成了对JDBC的核心流程的工作,包括SQL语句的创建和执行
f.仅需要传递DataSource就可以把它实例化
g.JdbcTemplate只需要创建一次
h.JdbcTemplate是线程安全类


   3、使用JdbcTemplate


方式一:(麻烦)
在Dao类中,用JdbcTemplate作为属性,用spring对JdbcTemplate进行注入。再对JdbcTemplate进行DataSource注入。


<bean id="dao" class="">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!--    配置JDBC模版  -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>


方式二:继承JdbcDaoSupport(简单)
      在Dao类中,继承JdbcDaoSupport。因为JdbcDaoSupport已经有了JdbcTemplate的引用,所以只要继承JdbcDaoSupport就相当于有了JdbcTemplate属性。
然后在注入Datasource(Dao类中不需要自己维护Datasource?c从父类继承下来)


<bean id="personDao" class="com.itheima12.spring.itheima12.PersonDao">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>


Dao类中jdbc操作中RowMapper的使用:(可以将ResultSet里的数据封装在一个持久的javaBean中)

1.写一个类实现RowMapper   public class AccountMapper implements RowMapper{}
2.在回调接口中,作为参数进行传入即可
this.getJdbcTemplate().query(sql,new AccountMapper);


   4、HibernateTemplate模板
1、如果一个DAO类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了。
2、如果一个DAO类没有继承HibernateDaoSupport,需要有一个HibernateTemplate的属性,在spring配置中注入SessionFactory。




*********Spring+Hibernate(配置)**********************************************


<!-- 方式一:引入sessionFactory(简单)-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>


<!-- 方式二:直接在applicationContext.xml中配置-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource" />
<!-- 映射文件所在的路径-->
<property name="mappingDirectoryLocations">
<list>
<!-- spring容器会去该包及子包下搜索所有的映射文件-->
<value>com/itheima12/spring/hibernate/transaction/domain</value>
</list>
</property>
<!-- Hibernate配置文件(hibernate.cfg.xml)中其余属性的配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>


七、Spring的事务管理器**************************************************************
spring的声明式事务处理:(让程序员不再关注事务)(只有事务管理器配置不一样)

     声明:由程序告诉spring容器,什么样的目标方法采用什么样的事务策略

     事务处理:是由spring容器来完成的

     crud操作:程序员做的事情
PlatformTransactionManager-->AbstractPlatformTransactionManager-->DataSourceTransactionManager/HibernateTransactionManager




需要引入名称空间(如下)+aop的名称空间
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd

***Spring+JDBC的事务管理器的配置方法***


   2.配置jdbc的事务管理器
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>


   3.配置通知
<tx:advice id="advice" transaction-manager="dataSourceTransactionManager">
   <tx:attributes>
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>//基本都是这种
<tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
   </tx:attributes>
</tx:advice>


   4.配置切入点
<aop:config>
<aop:pointcut expression="execution(* com.heima.service.*.*(..))" id="perform">
<aop:advisor advice-ref="advice" pointcut-ref="perform"/>
</aop:config`>


   注解形式:
1.<!-- 启动Spring的自动扫描功能-->
<context:component-scan base-package=""/>
2.<!-- 配置数据源dataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDaraSource" destroy-method="close">
     <property name="driverClassName" value="com.mysql.jdbc.Driver">
     <property name="url" value="jdbc:mysql://localhost:3306/JDBC">
     <property name="username" value="root">
     <property name="password" value="root">
</bean>
3.<!--配置JDBC模版-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
4.<!-- 配置jdbc事务管理层-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
5.<!-- 采用@Transaction注解方式使用事务-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager">


***Spring+Hibernate的事务管理器的配置***


需要在web中:
<!--   提前打开SessionFactory 的Session,延迟关闭Session会话 -->
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


   XML配置形式:
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<!--事务的声明-->
<tx:advice  transaction-manager="transactionManager" id="tx">
<tx:attributes>
<tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>

<!-- 切入点的配置-->
<aop:config>
<aop:pointcut 
expression="execution(* com.itheima12.spring.hibernate.transaction.service.impl.*.*(..))" 
id="perform"/>
<aop:advisor advice-ref="tx" pointcut-ref="perform"/>
</aop:config>

   注解形式:
1.<!-- 启动Spring的自动扫描功能-->
<context:component-scan base-package=""/>
2.<!-- 配置数据源dataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDaraSource" destroy-method="close">
     <property name="driverClassName" value="com.mysql.jdbc.Driver">
     <property name="url" value="jdbc:mysql://localhost:3306/JDBC">
     <property name="username" value="root">
     <property name="password" value="root">
</bean>
3.<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource" />
<!-- 映射文件所在的路径-->
<property name="mappingDirectoryLocations">
<list>
<!-- spring容器会去该包及子包下搜索所有的映射文件-->
<value>com/itheima12/spring/hibernate/transaction/domain</value>
</list>
</property>
<!-- Hibernate配置文件(hibernate.cfg.xml)中其余属性的配置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
4.<!--配置Hibernate模版-->
<bean id="hibeinateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
4.<!-- 配置Hibernate事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
5.<!-- 采用@Transaction注解方式使用事务-->
<tx:annotation-driven transaction-manager="transactionManager">


eg:service层注解形式:
@Transactionl(readOnly=true)
public class BusinessServiceImpl{

@Transactionl(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
public void save(){}
}
解释:方法的事务设置将被优先执行。
-------------------------------------------------------------HibernateCallback(Spring的回调接口)------------------------------------------
eg: hibernateTemplate.execute(new HibernateCallback<T>() {


@Override//可以得到session 可以在做你想做的事
public T doInHibernate(Session session) throws HibernateException,
SQLException {

return T;
}
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值