spring--入门

    xiaoxiao2025-07-28  4

    一、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; } });
    转载请注明原文地址: https://ju.6miu.com/read-1301164.html
    最新回复(0)