Spring学习笔记

       Spring 学习笔记

八种基本类型+String类型的注入
	配置文件:
	<bean id="user" class="injection.User">
		<property name="name">
			<value>james</value>
		</property>
		<property name="id">
			<value>123456</value>
		</property>
		<property name="password">
			<value>password123</value>
		</property>
		<property name="phone">
			<list>
				<value>18357004390</value>
				<value>18236888177</value>
			</list>
		</property>
		<property name="addresses">
			<set>
				<value>北京</value>
				<value>上海</value>
			</set>
		</property>
		<property name="email">
			<value>james@163.com</value>
		</property>
		<property name="product">
			<map>
				<entry>
					<key>
						<value>apple</value>	
					</key>
					<value>5</value>
				</entry>
				<entry>
					<key>
						<value>banana</value>
					</key>
					<value>6</value>
				</entry>
			</map>
		</property>
		<property name="properties">
			<props>
				<prop key="key1">value1</prop>
				<prop key="key2">value2</prop>
			</props>
		</property>
	</bean>

自定义类型注入:
	<bean id="uDAO" class="injection.UserDaoImpl"></bean>
	<bean id="userService" class="injection.UserServiceImpl">
		<property name="userDao">
			<ref local="uDAO"/>
		</property>
	</bean>

如何通过spring框架为用户自定义类型赋值?
一、set方法赋值
	1.创建对应的类  为成员变量提供set get方法
	2.配置applicationContext.xml
		<bean id="uDAO" class="injection.UserDAOImpl"></bean>
		<bean id="userService" class="injection.UserServiceImpl">
			<property name="userDAO">
				<ref local="uDAO"/>
			</property>
		</bean>
	3.编码  通过工厂获得userService对象
		ApplicationContext


注意:List Set Map 会根据存储的对象不同注入方式有所不同

二、通过有参构造为成员变量赋值
开发步骤:
	1.类  提供有参构造
	2.spring配置文件
		<bean id="c" class="constructor.Customer">
			<constructor-arg>     顺序要相同
				<value>James</value>
			</constructor-arg>
			<constructor-arg>
				<value>25</value>
			</constructor-arg>
		</bean>

三、自动注入
	概念:通过spring工厂自动扫描符合要求的对象为成员变量赋值
	开发步骤:
	<bean id="userDAO" class="xxx.UserDAOImpl"/>
	<bean id="userService" class="xxx.UserServiceImpl" aotowire="byType">

	</bean>
	aotowire:byType  Spring会在配置文件中自动扫描和UserServiceImpl成员变量
	类型相同的对象  进行赋值
	byName  Spring会在配置文件中自动扫描id和UserServiceImpl成员变量名字相同的对象  进行赋值

	自动注入的问题: 1.程序的可读性差  2.存在风险

综上所述:自动注入不建议使用


IOC ----- inverse of control   翻转控制
	概念:把由代码来控制成员变量的赋值 翻转到了配置文件中完成
	好处:解耦合
	原理:Spring的工厂   工厂设计模式

DI ------- dependency injection 依赖注入
	概念:当需要一个对象时,就可以等同于依赖它,那么久可以把这个对象作为成员变量
	,通过spring的配置文件进行注入。

FactoryBean 
	概念:创建复杂对象(没有构造方法的对象)

 	FactoryBean开发步骤:
 	1、实现接口  FactoryBean
 		书写创建复杂对象的代码,并把所创建的复杂对象作为方法的返回值返回。
 		public Object getObject(){
 			Configuration cfg = new Configuration().configure();
 			SessionFactory sf = cfg.buildSessionFactory();
 			return sf;
 		}

 		返回所创建的复杂对象的class类型
 		public Class getObjectType(){
 			return sf
 		}
 	2、配置文件

 	注意:如果在spring的配置文件中,配置的class类型是FactoryBean接口
 	的实现类,通过id获得的是它所创建的复杂对象。


Spring+Hibernate 整合

搭建开发环境
	1、jar
	2、配置文件   applicationContext.xml  hibernate.cfg.xml   xxx.hbm.xml
	3、预先配置(初始化) struts2 web.xml  Filter hibernate hibernate.cfg.xml配置参数

Spring+hibernate 整合思想
	hibernate ----DAO
	spring ------创建对象  依赖注入


如何限定简单对象的创建次数?
	<bean id="u" class="xxx.User" scope="singleton/prototype"/>
	scope: singleton  只会创建一次对象   默认值
		prototype   每次都会创建一个新对象


Spring高级特性:
1、生命周期
什么是生命周期?
	概念:spring工厂所创建的对象 什么时候创建 什么时候运行  什么时候销毁

	什么时候创建对象-----当spring工厂被创建时会自动把配置文件中所有的对象都创建出来
		节省创建对象的延损 提高效率
	什么时候活着--------工厂活着 对象就活着
	什么时候销毁对象-----工厂关闭,对象销毁(必须调用工厂的close方法 以为工厂关闭)

spring相关的生命周期方法:
	初始化方法(名字随便): spring会在创建一个对象之后 自动的调用初始化方法
	销毁方法(名字随便):spring会在销毁一个对象之前 自动的调用销毁方法
	<bean id="c" class="life.Customer" init-method="myInit" destroy-method="myDestroy"/>s


2、PropertyPlaceholderConfigure(配置信息参数化)
	概念:把spring配置文件中 那些需要经常修改的字符串信息从spring的配置文件中
		转移到一个小的配置文件中。

	PropertyPlaceholderConfigure开发步骤:
		1.准备小配置文件
			放置位置---src下随便
			properties结尾

		2.进行spring配置文件与小配置文件的整合
			<context property-placeholder location="classpath:/propertyplace/jdbc.properties"/>
		3.在spring经常需要修改的字符串所在位置${key}从小配置文件取值
			<context:property-placeholder location="classpath:/propertyplace/jdbc.properties"/>
			<bean id="conn" class="propertyplace.ConnectionFactoryBean">
				<property name="driver" value="${driver}"></property>
				<property name="url" value="url"></property>
				<property name="username" value="username"></property>
				<property name="password" value="${password}"></property>
			</bean>

3.CustomEditor(自定义类型转换器)
	类型转换器:spring提供的一种类,负责把配置文件中的字符串数据转换成成员变量对应的类型
	自定义类型转换器:spring框架内部没有提供特殊类型的类型转换器,程序员需要自己
			开发对应的类型转换器。

	自定义类型转换器的开发步骤:
		1、类 implements PropertyEditor
			extends PropertyEditorSupport
			1 获得spring配置文件中的字符串数据
			2 进行字符串数据的转换
			3 为成员变量进行注入

		2.配置文件
			1 声明:告知spring类的存在
			2 注册:告知spring这个类型应用于哪种类型的转换
				org.springfremeword.beans.factory.config.CustomEditorConfigure
				用于类型转换的注册

public class DateConverter extends PropertyEditorSupport {
	/**
	 * 1 获得spring配置文件中的字符串数据    text参数---<value>2016-7-13</value>
	 * 2 进行String ---Date转换
	 * 3 进行赋值
	 */
	@Override
	public void setAsText(String text){
		try {
			SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
			Date d = sd.parse(text);
			//赋值 把转换好的Date交给spring赋值给date
			setValue(d);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

配置文件:
<bean id="user" class="CustomEditor.User">
		<property name="name" value="james"></property>
		<property name="age" value="25"></property>
		<property name="date">
			<value>2016-7-13</value>
		</property>
	</bean>
	<bean id="dateConverter" class="CustomEditor.DateConverter"></bean>
	<bean id="customEditor" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry>
					<key>
						<value>java.util.Date</value>
					</key>
					<ref local="dateConverter"></ref>
				</entry>
			</map>
		</property>
	</bean>

	spring类型转换器的工作原理:
		1 发现Date日期转换 没有提供系统的类型转换器
		2 注册 
		<bean id="customEditor" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
			<property name="customEditors">
				<map>
					<entry>
						<key>
							<value>java.util.Date</value>
						</key>
						<ref local="dateConverter"></ref>
					</entry>
				</map>
			</property>
		</bean>
		3 调用DateConverter DateConverter implements PropertyEditor setAsText();
		4 setValue(d); 交给spring为date赋值


AOP编程(Aspect oriented programming)   面向切面编程
	核心:代理设计模式 Proxy
	概念:通过代理类 为原始的service增加额外功能
	好处:因为引入代理类,原始service不再书写额外功能,被修改的几率大大减小,
		提高程序的维护性
	代理类开发要素:代理类=原始的service+额外功能+实现相同的接口

	静态代理设计模式:一个原始类对应一个世纪存在的代理类
		静态代理设计模式的弊端:
			1 不利于项目的管理  维护
			2 额外功能的代码冗余
			3 额外功能不好维护

	动态代理
		spring动态代理设计模式概念:
			spring框架通过引入动态代理机制 解决了静态代理中的问题  本质上没有区别
	spring动态代理的开发思路:
		1 原始类  没有额外功能的service 只负责业务 DAO调用
		2 额外的功能 Advice接口
			MethodBeforeAdvice 额外功能运行在原始方法运行之前执行
			AfterReturningAdvice 额外功能运行在原始方法运行之后执行
			MethodInterceptor 额外功能运行在原始方法运行之前 之后执行
			ThrowsAdvice 额外功能运行在原始方法出现异常时执行
		3 切入点  切入点决定额外功能加入的位置(决定哪个原始方法加入额外功能)
		<aop:config>
			<!-- 所有方法都加入额外功能 -->
			<aop:pointcut expression="execution(* *(..))" id="pc"/>
			<aop:advisor advice-ref="before" pointcut-ref="pc"/>
		</aop:config>
		4 组装  额外功能+切入点 整合
			<aop:advisor advice-ref="before" pointcut-ref="pc"/>

	编码:
		ApplicationContext ctx = new ClassPathXmlApplicationContext("xxx.xxx.xml");
		UserService us = (UserService)ctx.getBean("原始对象的id值获得代理对象")

切入点 (PointCut)决定额外功能加入的位置
	1 expression="execution(切入点表达式)"
	2 切入点表达式
		* *(..)   所有的方法都加入额外功能(不关心方法属于哪个类)
		* *(..)  ---- public void add(int a,int b);
		         ---- public void      add    (int a,int b)
		 对login方法加入额外功能  * login(..)
		 其他---  * login(Stiring,..)
		 参数类型不是java.lang包里的类型 --- 如 * register(dynamic.User)

		以类作为切入点
			* *.UserService.*(..) ------UserService类中的所有方法
			public int 包.类.方法(参数)
		以包为切入点同理
		注意:  * dynamicproxy.*.*(..)   当前包
		       * dynamicproxy..*.*(..)    ..表示当前包及其子包

		 复合切入点  and or not
		 execution(* login(..)) or execution(* showOrder(..))

AOP编程 Aspect Oriented Programming 面向切面编程
	OOP 面向对象编程: 以对象为基本单位的程序开发
	C   面向过程编程: 以过程(函数)为基本单位的程序开发
	AOP 面向切面编程: 以切面(切入点+额外功能)为基本单位的程序开发

	概念:本质上就是Spring动态代理的开发,通过代理类为原始类增加额外的功能 利于维护
	好处:利于维护
	原理:代理设计模式

研究Spring动态代理(AOP)
	1 spring框架如何在程序运行的过程中动态的创建代理类?
		JDK Proxy newProxyInstance();方法的作用:可以保证在运行过程中为原始类创建代理
		类加载器:类加载器负责把一个.class文件读入JVM 类加载器的来源 .class文件
	2 为什么在spring工厂中 通过原始对象的id而获得代理对象?
		基于BeanPostProcessor机制

Spring框架提供了JdbcTemplate封装jdbc开发中冗余代码
	1、JdbcTemplate用在哪
		DAO层
	2、JdbcTemplate怎么使用
		JdbcTemplate进行CRUD

		jdbcTemplate进行CUD(增删改)
		jdbcTemplate.update(String sql,Object[] args)
		例如:
		jdbcTemplate.update("insert into t_user(name,password") 
			value(?,?),new Object[]{"james","123456"}

		jdbcTemplate进行R(查询)
			单行结果的查询 封装一个对象
			Object ret = jdbcTempalte.queryForObject(String sql,
									Object[] args,RowMapper rowMapper)	
			多行结果查询 封装成List<对象>
			List<Object> ret = jdbcTemplate.query(String sql,Object[] args,
									RowMapper rowMapper)
JdbcTemplate开发步骤
	1 编码
		DAO{
			private JdbcTemplate jdbcTemplate;
			set
			get
			jdbcTemplate.update();
		}
	2 配置
		DataSource
		JdbcTemplate
		DAO

Spring中如何控制事务
	核心思想:通过动态代理(AOP)为业务层增加事务这种额外功能
	1 原始对象
	2 额外功能
		1 控制事务的代码
			org.springframework.jdbc.datasource.DataSourceTransactionManager
			注入DataSource连接池
		2 事务属性
			隔离属性(isolation)
				概念:描述事务解决并发问题的能力
				并发:多个用户同一时间访问了同一个数据
				并发问题:
					1 脏读  ISOLATION_READ_COMMITED  默认值
						一个用户读取了另一个用户没有提交的数据,产生数据不一致
					2 不可重复读  ISOLATION_REPEATABLE_READ(数据库加行级锁)
						一个事务中对相同的数据进行多次查询 而查询结果不一致
					3 幻影读  ISOLATION_SERIALAZABLE (数据库加表级锁)
						一个事务中对相同数据进行统计 但是统计的结果不一致
			传播属性
				概念:描述事务解决嵌套问题的能力
				PROPATATION_REQUIRED:如果外部没有事务,开启新事务  适合增删改  默认值
									如果外部存在事务,融合到外部事务中
				PROPAGATION_SUPPORTS:如果外部没有事务,不开启事务 适合查询
									如果外部存在事务,融合到外部的事务总
			只读属性 raad-only
				如果本次业务为查询业务 指定只读属性 提高查询效率 值为true false
			超时属性 timeout 默认值为-1
				如果存在别的事务为当前访问的数据加锁,通过timeout属性指定最多等待多少秒
			异常属性
				spring默认对RuntimeException及其子类 回滚策略
							Exception 及其子类  提交策略
				概念:通过异常属性 改变spring在事务处理中 对异常采取默认策略
				rollback-for="异常的全限定名"  no-rollback-for="异常的全限定名"
		3 切入点
		4 切面 整合

Spring DAO层对Hibernate技术的支持(官方版本spring+hibernate整合)
	org.springframework.orm.hibernate3.HibernateTemplate 替换原有的Sessin对象

	hibernateTemplate:提供很多和Session方法名及作用一直的方法
	结论:hibernateTemplate封装了原始的Hibernate中的Session对象
	目的:在原有Session功能的基础之上,进行扩展,进行增强
	public class HibernateTemplate{
		private Session session;
		public void save(){
			session.save();
		}
	}
Spring+Hibernate官方版本 整合开发步骤:
	1 HibernateTemplate封装session同时自动把session绑定到线程(自动调用
		getCurrentSession)
	2 HibernateTemplate自动在DAO开启小的事务
	3 简化HQL开发
		List l = hibernateTemplate.find(String sql,Object[] args);
		String sql:from User as u where u.name=?
		Object[] args:new Object[]{"james
		注意:find只会返回List集合
	4 HibernateTemplate.execute() 方法
		救命用的:在某些特定的场景下,hibernateTemplate提供的方法解决不了
			对应的问题,那么就需要使用execute()方法解决
		public class MyHibernateCallback implements HibernateCallback{
			public Object doInHibernate(Session session){
				Query query = session.createQuery("from User as u where u.name=?");
				query.setString(0,"james");
				return query.uniqueResult();
			}
		}

分页操作
	Query query = session.createQuery();
	query.setFirstResult((pageIndex-1)*3;
	query.setMaxResults(3);	
	query.list();

	public List<User> queryUsersByPage(final int pageIndex){
		List<User> users = hibernateTemplate.execute(new HibernateCallback(){
			@Override
			public Object doInHibernate(Session session) 
					throws HibernateException,SQLException{
				Query query = session.createQuery();
				query.setFirstResult((pageIndex-1)*3;
				query.setMaxResults(3);	
				return query.list();
			}
		})
		return users;
	}

Spring+Struts2整合思路:
	Action依赖Service 需要通过spring注入service
	UserAction implements Action{
		private Service;
		set  get
		public String execute(){
		
		}
	}
Struts2+Spring整合开发步骤
	准备:搭建开发环境
		1 jar  struts2-spring-plugin.jar
		2 配置
		3 预先配置
	1 创建service
	2 开发Struts2的Action
		1 implements Action
			extends ActionSupport
		2 配置struts.xml
	3 创建工厂
	ApplicationContext ctx = new WebApplicationContext("applicationContext.xml");
	org.springframework.web.context.ContextLoaderListener
	作用:封装了创建工厂的代码WebApplicationContext
	使用:直接在web.xml进行配置即可
	<listener>
  		<listener-class>org.springframework.web.context.ContextLoaderListener
  		</listener-class>
  	</listener>
  	<context-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:applicationContext.xml</param-value>
  	</context-param>

 SSH整合
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值