Spring总结
来源:互联网 发布:阿迪达斯淘宝旗舰店 编辑:程序博客网 时间:2024/06/10 22:05
Spring
Spring依赖于spring工厂,管理对象创建,可以自动new对象,是个轻量级项目(轻量级:学习成本低,记东西得少-_-!)
IoC:Inverse of Controller(控制反转)
对象创建的控制权转移到程序的外部(Spring),完成解耦
DI:Dependency Injectjion 依赖注入(依赖谁就注入谁)
IoC的目的是为了解耦,对象创建的控制权转移到程序外部,需要使用对象时,通过DI来实现。
DI的两种实现方法:set注入和构造注入
另外还可以静态工厂注入
;
通过Spring实现IoC和DI:
1、SpringIoC 对象创建的控制权转移到 Spring容器中。2、SpringIoC容器:放各种JavaBean(Java对象的容器)/Spring bean工厂(工厂:造对象)。
使用Spring实现IoC的优势:
彻底的IoC,把对象创建的过程由硬编码改成了配置文件,进一步解耦,后期只修改配置文件即可,无需进行二次编译。
硬编码:代码中修改,硬编译,服务器需要重新部署,而配置文件则不需要
SpringIoC开发步骤:
1、加载jar包:
spring-beans-3.2.14.RELEASE.jarspring-context-3.2.14.RELEASE.jarspring-core-3.2.14.RELEASE.jarspring-expression-3.2.14.RELEASE.jar此外,Spring运行还需导入commons-logging的jar包:com.springsource.org.apache.commons.logging-1.1.1.jar其中spring-core,和spring-beans提供框架的基本组成部分,包括IOC和依赖注入功能。
2、编写Spring配置文件:
2.1、 applicationContext.xml(Spring上下文配置),一般放到src根目录,主要配置IoC和DI
①、打开页面:spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\beans.html②、在basic structure of XML-based configuration metadata中找到DTD③、复制到applicationContext.xml中
<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.xsd"></beans> <!-- 不要忘了加上beans的末标签 --><!-- xmlns的“ns”相当于struts2中的namespace-->
property标签:实现DI:默认会去调用set方法bean class:默认调用无参构造,调用有参使用constructor-argconstructor-arg:index 参数的个数、位置、类型、要和构造方法匹配
2.2、实现Spring DI
<!-- 一个bean对应一个Java对象 --><!-- name/id:对象名 --><!-- class:全限定名(包名+类名)默认调用无参构造实例化对象 --><bean name="a4" class="domain.A4"></bean><bean id="b5" class="domain.B5"></bean><bean name="colorInk" class="domain.Color"></bean><bean name="blackInk" class="domain.Black"></bean>
2.2.1、 set注入:
<bean name="printer1" class="domain.Printer"> <!-- set注入property标签:自定义引用类型对象注入使用ref,java数据类型用value进行注入 --> <property name="ink" ref="blackInk"></property> <property name="paper" ref="a4"></property> <property name="brand" value="联想"></property></bean>
2.2.2、 构造注入:
<!-- index按照下标注入 --><bean name="printer2" class="domain.Printer"> <constructor-arg index="0" ref="a4"></constructor-arg> <constructor-arg index="1" ref="colorInk"></constructor-arg></bean>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<!-- name属性按照参数名注入 --><bean name="printer2" class="domain.Printer"> <constructor-arg name="paper" ref="a4"></constructor-arg> <constructor-arg name="ink" ref="colorInk"></constructor-arg></bean>
2.2.3、 静态工程
<!-- 通过静态工厂方法 --><bean name="printer3" class="beanfactory.PrinterFactory" factory-method="getPrinter"> <property name="ink" ref="blackInk"></property> <property name="paper" ref="a4"></property> <property name="brand" value="联想"></property></bean>
<!-- 通过非静态的工厂方法new对象:首先要把工厂先new出来 --><bean name="pf" class="beanfactory.PrinterFactory"></bean><!-- 使用工厂对象的intancePrinter()创建Printer对象 --><!-- factory-bean:指定使用的工厂对象名 --><bean name="printer4" factory-bean="pf" factory-method="instancePrinter"> <property name="ink" ref="blackInk"></property> <property name="paper" ref="a4"></property> <property name="brand" value="三星"></property></bean>
/* * 打印机工厂 */public class PrinterFactory { //静态工厂方法 public static Printer getPrinter(){ return new Printer(); } //实例工厂方法 public Printer instancePrinter(){ return new Printer(); }}
3、P命名空间:
3.1、 在DTD中加入xmlns:p="http://www.springframework.org/schema/p"
3.2、 使用P命名空间无须再使用property标签
<!-- 自定义引用类型后加-ref,普通类型:p:属性名 --><bean name="printer5" factory-bean="pf" factory-method="instancePrinter" p:ink-ref="blackInk" p:paper-ref="b5" p:brand="佳能"></bean>
4、C命名空间:
4.1、 在DTD中加入xmlns:c="http://www.springframework.org/schema/c"
4.2、 替换constructor-arg,使用c命名空间构造器注入
<!-- 自定义引用类型后加-ref,普通类型:c:属性名 --><bean name="printer6" class="domain.Printer" c:paper-ref="a4" c:ink-ref="colorInk"></bean>
5、通过Spring实现各种类型的注入
/* java基本属性类型(包括String,包装类):value 自定义应用类型:ref Proprety:props List集合:list Set集合:set Map集合:map 数组:list*/public class DIBean { private List<String> list; private Set<Integer> sets; private Map<String, String> map; private Properties prop; private int nul; ······ //省略Get/Set、构造方法}
<bean name="diBean" class="domain.DIBean"> <property name="list"> <list> <value>abc</value> <value>你好</value> </list> </property> <property name="sets"> <set> <value>12</value> <value>14</value> </set> </property> <property name="map"> <map> <!-- map中要加entry子标签 一个entry对应一个KV --> <entry key="" value=""></entry> <!--key-ref表示 应用的类型 <entry key="" key-ref=""></entry> --> <entry key="name" value="凯子"></entry> <entry key="childrenSum" value="10"></entry> </map> </property> <!-- Propeties对应.properties文件,其实就是map,key,value默认都是String类型 --> <!-- 目的就是为了替换.properties --> <property name="prop"> <props> <prop key="url">jdbc:mysql://localhost:3306/XXX</prop> <prop key="driverClass">com.mysql.jdbc.Driver</prop> <prop key="username">xxoo</prop> <prop key="password">xxoo</prop> </props> </property> <!-- 基本注入使用value --> <property name="nul" value="100"></property></bean>
6、测试类中获取Spring为我们创建的Bean
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
注意:
1、设值注入bean一定要有set方法,构造注入一定要有构造方法。2、jutil测试的注解:@Before作用在@Test之前
使用注解进行IoC和DI
1、applicationContext.xml中添加context命名空间,并开启扫描
<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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启组件扫描 哪些类需要添加注解,就扫描类所在包,多个包之间用逗号分隔 --> <context:component-scan base-package="domain"></context:component-scan> <!-- base-package:要扫描的包(如果有其他的包可以添加逗号链接) --> <!-- conponent:组建 --></beans>
2、Spring常用的注解
IoC注解:添加注解的类,spring会为我们创建对应对象
@Component:万能IoC注解,在需要实例化的类头上添加@Component,实例化默认的对象名是类名首字母小写,@Component("对象名"),相当于bean name例:Printer--------printer
@Component的三个子类:
@Repository:dao层类@Service:service层@Controller:控制层
DI注解:
spring官方DI注解:
@Autowired:默认按照类型查找,查找到该类型对象,自动注入该对象@Quarfer("对象名"):按照对象名去查询对象,找到自动注入@Autowired和@Quarifer结合使用
JDK DI注解:
@Resource:默认按照名字进行查找@Resource:默认去找名字为service对象,找不到再按照类型查找private UserService service;@Resource(name=“对象名”):按照指定名字进行查找
总结:
IoC注解添加到类头上:new 对象DI注解添加到属性上:实现注入使用注解无需在使用 set方法
易错点:
1、在一个配置文件中不能定义重名的对象2、注解也不允许有同名的对象、不能注入同名的对象3、在springIoC容器中可以有两个或多个类型相同的对象,但注入的时候一定按照名称注入,不能按类型注入(配置文件中不能定义重名的对象)4、对普通类型的注入用:@Value("值")
使用注解为什么可以不添加set或构造方法?
因为使用注解实现DI,靠的是反射机制,通过反射得到Field,然后打开该filed的访问权限(filed.setAccessible(true)),最后通过调用filed.set(Object,value)实现注入。
为什么要使用Spring对各种框架进行整合?
1、使大量业务类的对象交由Spring实例化和DI,统一了对Bean的管理、也就是使用SpringIoC和DI实现和其他的框架的结合2、同时Spring优化了一些框架的开发,比如Spring对Hibernate操作进行了封装(HibernateTemplate),简化了代码。3、通过SpringAOP可以进一步对业务代码和非核心代码进行解耦,比如事物操作。
SpringAOP:
AOP:AspectOrientedPrograming(面向切面编程)Aspect:切面
根本作用是为了解耦,在不修改原业务代码的基础上增加功能通用功能(所有表都需要事物管理)。AOP是个动态过程,一般情况下,非核心业务使用AOP:事务管理,日志记录
Spring和hibernante结合
Spring整合Hibernate,主要做两件事:提供事务级session和声明式的事务控制。
1、不保留hibernate的cfg.xml,把hibernate的配置声明到spring的配置文件中
2、保留hibernate cfg.xml(无需掌握);
Spring优化Hibernate步骤:
1、加载jar包:
c3p0-->mysql-connection-->hibernate Required-->SpringIoC基本包---->SpringAOP基本包log4j下slf4j两个静态日志包-->spring整合事务
2、
1、加载db.properties
db.properties# .properties是一种存储数据的配置文件# db.properties是存数据库的配置文件# .properties是key-value的结构的,而且KV默认都是String类型# 使用配置文件的目的是为了解耦,后期需要修改数据配置信息无需再修改代码URL= jdbc:mysql://127.0.0.1:3306/user_infoUSER = rootPASSWORD = rootDRIVER = com.mysql.jdbc.Driver
applicationContext.xml<!-- Spring加载.properties文件 --> <context:property-placeholder location="classpath:db.properties"/>
2、配置C3P0数据源
<!-- 使用数据库连接池的时候首先在dataSource里注入数据库连接参数 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${DRIVER}"></property> <property name="jdbcUrl" value="${URL}"></property> <property name="user" value="${USER}"></property> <property name="password" value="${PASSWORD}"></property></bean>
3、创建 SessionFactory : LocalSessionFactoryBean
创建的同时注入C3P0数据源dataSource
、hibernate配置参数hibernateProperties
,并且将使用注解的包进行扫描开启packagesToScan
<!-- LocalSessionFactoryBean:封装了hibernate.current_session_context_class=thread(进行了Session和线程的绑定)--><bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"></bean>
3.1、 注入c3p0数据源
<!-- 注入c3p0数据源 --><property name="dataSource" ref="dataSource"></property>
3.2、 Spring中配置Hibernate
<!-- hibernateProperties:hibernate的配置信息 --><property name="hibernateProperties"> <!-- java.util.Prperties的注入可以简化为value --> <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true hibernate.format_sql=true hibernate.hbm2ddl.auto=update </value></property>
3.3、 开启注解
<!-- 使用hibernate注解需要开启包扫描 --><!-- packagesToScan:String[] 给数组注入值使用list --><property name="packagesToScan"> <list> <value>需要扫描的包名</value> </list></property>
3.4、 配置映射文件的包路径 如果不想配置映射文件直接省去即可
<!-- 配置映射文件的包路径 --><property name="mappingDirectoryLocations"> <list> <value>com/lanou/domain</value> </list></property>
4、DAO层类中使用HibernateDaoSupport注入SessionFactory的方式
主要用来获取session
如何获取Hibernate原生Session?
1、注入SessionFactory2、通过SessiongFactory获取session
4.1、注解的方式
①、Dao层继承HibernateDaoSupport②、使用set注入SessionFactory得到HibernateTemplate (可以把HibernateTemplate近似的理解为Hibernate.Session)如:向数据库添加数据 getHibernateTemplate().save(user); 替换 session.save(user);
@Autowired不仅可以写在属性上,实现对属性的注入,还可以写在set方法上,实现set注入
@Autowired@Qualifier("sessionFactory1")private void setSuperSessionFactory(SessionFactory sessionFactory){ super.setSessionFactory(sessionFactory);}
4.2、配置文件声明的方式(使用配置文件无需写setSuperSessionFactory方法)
不继承hibernateDaoSupport使用HibernateTemplate:
1、SpringIoC实例化HibernateTemplat,需要注入sessionFaciory2、使用HibernateTemplate做Dao的成员变量,使用DI注入HibernaeTemplate实例注意:①、使用Set注入(property) 一定要有set();②、 类的版本要一致,建议使用Hibernate5
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"/></bean><bean id="userDao" class="dao.impl.UserDaoImpl" scope="prototype"> <property name="hibernateTemplate" ref="hibernateTemplate"/></bean>
注意:
springIoC实例化的对象默认是单例的:singleton
通过scope来配置Bean的模式
scop常见值:
singleton(单例)prototype(每次使用都会创建一个新的实例)request(把该对象添加到reuqest请求对象中request.setAttribute("beanName", bean))session(session.setAttribute("beanName", bean))
//使用HibernateTemplate做dao的成员变量,后期springDI//HibernateTemplate是线程安全的,其底层封装了currentSession(也就是和线程绑定的session)private HibernateTemplate hibernateTemplate;//使用set注入(property)一定要有set()public HibernateTemplate getHibernateTemplate() { return hibernateTemplate;}public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate;}//不用get/set,就用注释进行注入
**4.3、**Hibernate中 getCurrentSession()和openSession()的区别:
1、getCurrentSession是线程安全的,底层还是OpenSession,他需要开启事务,在事务提交的时候会自动关闭session,所以不能session.close();不要忘了配置:hibernate.current_session_context_class=thread2、openSession:线程非安全,一个CRUD对应一个open close,查询无须开启事务
4.3.1、 getCurrentSession()
方法获取session
public my_user findUser(my_user user) throws UserNotFoundException { Session session = sessionFactory.getCurrentSession(); Transaction tx = session.beginTransaction(); // 开启事务 Query query = session.createQuery("from user_info where name=:name and password=:pwd"); query.setParameter("user_name", user.getUser_name()); query.setParameter("user_password", user.getUser_password()); my_user returnUser = (my_user) query.uniqueResult(); tx.commit(); // 提交事务 if(returnUser==null){ throw new UserNotFoundException("该用户不存在"); } return returnUser;}//如果配置了 hibernate.current_session_context_class=thread 那么必须进行编程式事务管理//此段代码已经进行了编程式事务管理,所以需要在applicationContext.xml中配置
4.3.2、 openSession()
方法获取session
public my_user findUser(my_user user) throws UserNotFoundException { Session session = sessionFactory.openSession(); Query query = session.createQuery("from user_info where name=:name and password=:pwd"); query.setParameter("name", user.getName()); query.setParameter("pwd", user.getPassword()); user_info returnUser = (user_info) query.uniqueResult(); session.close(); //一个CRUD对应一个open close if(returnUser == null){ throw new UserNotFoundException("该用户不存在"); } return returnUser;}
5、通过调用HibernateTemplate的API实现CRUD
hibernateTemplate的常用方法:
void delete(Object entity):删除指定持久化实例deleteAll(Collection entities):删除集合内全部持久化类实例find(String queryString):根据HQL查询字符串来返回实例集合findByNamedQuery(String queryName):根据命名查询返回实例集合findByExample:会对查询自动添加where条件,查询参数封装到user里get(Class entityClass, Serializable id):根据主键加载特定持久化类的实例save(Object entity):保存新的实例saveOrUpdate(Object entity):根据实例状态,选择保存或者更新update(Object entity):更新实例的状态,要求entity是持久状态setMaxResults(int maxResults):设置分页的大小
注意:
HIbernateTemplate.find( )
方法返回list<?>
,即find( )
方法的返回值都是list
HibernateTemplate建议使用find(), find就是Hibernate.Query的封装 find(hql):List<?>
find(hql, Object...params)
:带查询条件的
6、使用SpringAOP进行事务管理
日后数据库事务管理一般交由spring处理,spring通过AOP的方法实现无侵入式事务。
<!-- 声明spring事务管理器:需要注入sessionFactory --><!-- 把SessionFactory交由了transactionManager管理,这样我们无须在关注事务 --><bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property></bean><!-- 开启事务注解 --><tx:annotation-driven transaction-manager="transactionManager"/>
基于注解的Spring事务管理
1、初始化Spring事物管理器:需要注入SessionFactory2、开启事物注解3、在业务层(Service)加@Transactional注解
spring和hibernate结合总结
1、db.propreties---->c3p0 DataSource--->SessionFactory------>Dao2、开启AOP事务:SessionFactory----->TransactionManager3、dao---->service--->controller
编程技巧:
如和获取一些常见类的全限定名?
如:
ConboPooledDataSource
HibernateTransactionManager
LocalSessionFactoryBean
OpenSessionView
使用快捷键:ctrl+shift+T
(如果没反应,可能是热键冲突,比如qq的快捷键),可以找到该类的全限定名。
Spring和struts结合
优化Strurs开发(可以被替换)
Spring和Mybatis结合
优化Mybatis开发
SpringMVC,是Struts的替换者
- Spring总结
- Spring总结
- spring总结
- spring总结
- spring总结
- Spring总结
- spring 总结
- spring总结
- Spring总结
- Spring 总结
- spring总结
- spring 总结
- spring 总结
- spring总结
- Spring总结
- Spring总结
- Spring总结
- spring 总结
- 笔记10 | 学习整理静态static 和 终态final
- 线段树 (入门篇)
- JVM与GC
- 如何提高测试效率
- object常用的方法有哪些
- Spring总结
- 二叉树创建以及遍历
- 第二章 Spring MVC入门 —— 跟开涛学SpringMVC
- 设计模式
- thinkcmf
- 【Python】【matplotlib】键鼠响应事件
- 打造“国际村”工作环境,弋果美语一路坚持!
- CodeForces
- Python3常用内置函数