Spring
目的: 解决企业应用开发的复杂性
功能: 使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围: 任何java应用
简单来说,Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架
1.轻量: Spring是轻量的,基本版本大约2MB
2.IOC(控制反转):
之前我们都是自己创建对象,管理对象.控制反转就是将对象的管理交给spring,我们只需要使用对象即可. 实现了松散耦合
3.DI(依赖注入):
IOC的一个特殊体现.我们在使用A对象时,在A的内部必须依赖B的对象,我们在获取A对象时,将B对象就注入到A对象中
4.AOP(面向切面的编程):
对面向对象的一个完善和补充,就是将面向对象中各个不同的业务模块需要使用到的共同的功能提取出来,通过动态代理模式在不影响现有的业务模块的前提下,为业务模块扩展功能. 所以一般AOP就是用在一些系统级别的功能配置上.
5.容器: Spring 包含并管理应用中对象的生命周期和配置
6.MVC框架: Spring在原有的基础上,有提供了web应用的MVC模块.
7.事务管理:
Spring提供了一个持续的事务管理接口,可以扩展上至本地事务下至全局事务.
8.异常处理:
Spring提供方便的API把具体技术异常相关的异常
(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
Spring中hibernate的配置
<!--sessionFactory.xml-->
<!-- 配置hibernate session工厂类似于 cfg 配置 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 其它配置 -->
<property name="hibernateProperties">
<props>
<!-- 数据库方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<!-- 自动建表 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- 控制台是否显示sql语句 -->
<!--show_sql: 是否把hibernate运行的sql语句显示到控制台 -->
<prop key="hibernate.show_sql">true</prop>
<!-- format_sql:输出到控制台的sql语句是否进行排版,便于阅读 -->
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<!-- 交由注解扫描实体类,省去了以前hibernate的配置文件,自动生成数据表 -->
<property name="packagesToScan" value="com.xalo.model." />
</bean>
<!--spring中hibernate事务配置 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!--设置事务通知中的方法 -->
<tx:advice transaction-manager="transactionManager" id="tx">
<tx:attributes>
<tx:method name="*" read-only="false" />
</tx:attributes>
</tx:advice>
<!--哪些方法需要添加增强功能 -->
<!-- aop配置 代理配置 proxy-target-class:不使用自动代理 -->
<aop:config proxy-target-class="false">
<!-- 切入点的配置 expression:要额外增加功能的方法 返回值 包名 类名 方法名-->
<aop:pointcut expression="execution(* com.xalo.daoImpl.*.*(..))" id="mypointcut" />
<!--环绕增强 -->
<aop:advisor advice-ref="tx" pointcut-ref="mypointcut" />
</aop:config>
<!-- 自动指定代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--dataSource.xml-->
<!-- 四本设置 -->
<!-- 配置数据源,数据库连接池配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 数据库驱动 -->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<!-- 数据库地址 -->
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/MHMS?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
<!-- 数据库用户名 -->
<property name="user" value="root"/>
<!--数据库密码 -->
<property name="password" value="12345678"/>
<property name="maxPoolSize" value="10"></property>
<property name="minPoolSize" value="3"></property>
<property name="maxIdleTime" value="600"></property>
<property name="initialPoolSize" value="3"></property>
<property name="acquireIncrement" value="5" />
<property name="checkoutTimeout" value="300000"></property>
<property name="idleConnectionTestPeriod" value="800"></property>
<property name="acquireRetryAttempts" value="30" />
<property name="maxStatements" value="0" />
<property name="breakAfterAcquireFailure" value="false" />
</bean>
什么是Spring IOC容器:
之前我们都是自己创建对象,管理对象.控制反转就是将对象的管理交给spring,我们只需要使用对象即可. 实现了松散耦合.
Spring IOC负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期).
IOC的优点:
IOC把应用的代码量降到最低,使应用容易测试,单元测试不在需要单例和JND查找机制.最小的代价和最小的侵入性使松散耦合得以实现.IOC容器支持加载时的恶汉式初始化和懒加载.
Bean常用的属性:
autowire(自动装配):
Spring简化了Bean的配置,提供了自动装配(autowire)机制,Spring本身为autowire属性提供了五个选项:
1.no:
默认不采用autowire机制. 我们需要使用依赖注入,只能用标签
2.byName:
通过属性的名称自动装配(注入).
3.byType:
通过类型自动装配(注入)
如果容器中包含多个这个类型的bean,Spring将会抛出异常.如果没有找到这个类型 的bean,那么注入动作将不会执行.
4.constructor:
通过构造函数的参数类型来匹配(注入),
如果在容器中找不到匹配的类的bean,将抛出异常,因为Spring无法调用构造函数实例化这个bean
5.default:
采用父级标签(即beans的default-autowire属性)的配置.
其中byType和constructor模式也支持数组和强类型集合(指定集合元素类型).如果集合和Map集合,那么Map的key必须是String类型.
scope: spring支持的几种bean的作用域
1.singleton:
单例模式 默认, bean在每个Spring IOC容器中只有一个实例
在beanFactory作用范围内,只维护此bean的一个实例.在服务器启动时创建.主要用于service dao层还有一些utils工具类,只需要在服务器启动时初始化一次即可.
2.prototype:
原型模式,一个bean的定义可以有对个实例
每次getBean获取对象时,都重新实例化一个对象.在SSH项目中主要作用于action对象,这种方式一般在服务器启动时不会创建对象,在每次使用时才会创建.
3.request:
将该对象放在request域中
4.session:
将对象放在session域中
5.global session:
全局session
什么是Spring 的依赖注入,有哪些方法进行依赖注入
IOC的一个特殊体现.我们在使用A对象时,在A的内部必须依赖B的对象,我们在获取A对象时,将B对象就注入到A对象中
1.Setter注入: 根据property标签的name属性的值去找对应的setter方法
<bean id="setter" class="com.xalo.action.SetterAction">
<property name="loginService" ref="service" />
</bean>
2.构造器注入:
保证了一些必要的属性在Bean实例化时就设置,并且确保了bean实例在实例化后就可以使用
1.在类中,不用为属性设置setter方法,只需要提供构造方法即可
2.在构造文件中配置该类bean,并配置构造器,在配置构造器中使用
缺点: 不够灵活,会影响对象的创建效率
<bean id="action" class="com.xalo.action.LoginAction">
<constructor-arg name="loginService" ref="service" ></constructor-arg>
</bean>
3.静态工厂注入
4.实例化工厂注入
Spring应用程序看起来像什么
一个定义功能的接口
实现包括属性,setter和getter方法,功能等
Spring AOP
Spring的XML配置文件
使用该功能的客户端编程
依赖注入
BeanFactory和ApplicationContext区别
BeanFactory:Spring里面最底层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能
ApplicationContext: 应用上下文,继承BeanFactory接口,它是Spring的更高级别的容器,提供了更多的有用的功能.
(1)国际化
(2)访问资源
(3)载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层
BeanFactory在启动时不会去实例化Bean,在容器中拿Bean的时候才会去实例化
ApplicationContext在启动的时候就把所有的Bean全部实例化了.它还可以为Bean配置lazy-int=true来让Bean延迟实例化.
常见的ApplicationContext实现方式:
1.ClassPathXmlApplicationContext:
从classpath的XML配置文件中读取上下文,并生成上下文定义.应用程序上下文从程序环境变量中取得
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
2、FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。
ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
3、XmlWebApplicationContext:由Web应用的XML文件读取上下文。
Spring Bean的生命周期
Spring Bean factory负责管理在spring容器中被创建的bean的生命周期.
Bean的生命周期由两组(call back) 方法组成
//初始化之前调用的回调方法
//销毁之前调用的回调方法
Spring框架提供了以下四种方式来管理bean的生命周期事件:
InitializingBean和DisposableBean回调接口
针对特殊行为的其他Aware接口
Bean配置文件中的Custom init()方法和destroy()方法
@PostConstruct和@PreDestroy注解方式
<beans>
<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"
init-method="customInit" destroy-method="customDestroy"></bean>
</beans>
Spring框架中的单例Beans是线程安全的吗?
Spring框架并没有对bean进行任何多线程的封装处理.
如果你的bean有多中状态的话(比如 View Model对象),就需要自行保证线程安全.
如何在Spring中注入一个Java Collection?
Spring提供了以下四种集合类的配置元素:
<list> : 该标签用来装配可重复的list值。
<set> : 该标签用来装配没有重复的set值。
<map>: 该标签可用来注入键和值可以为任何类型的键值对。
<props> : 该标签支持注入键和值都是字符串类型的键值对。
Spring框架中都用到的设计模式
/*
*代理模式:在AOP和remoting中被用的比较多
*单例模式:在spring配置文件中定义的bean默认为单例模式
*模板方法:用来解决代码重复的问题.比如: RestTemplate, JmsTemplate, JpaTemplate
*前端控制器: Spring提供了DispatcherServlet来对请求进行分发
*视图帮助(View Helper):Spring提供了一系列的JSP标签,来辅助将分散的代码整合在视图里
*依赖注入:贯穿于BeanFactory/ApplicationContext接口的核心理念
*工厂模式: BeanFactory用来创建对象的实例
*/
Spring支持的事务管理类型:
编程式事务管理: 通过编程的方式管理事务,灵活性高,但很难维护
声明式事务管理: 将事务管理和业务代码分离.只需要通过注解或者XML配置管理事务.
Spring事务管理有哪些优点?
1.为不同的事务API(JTA, JDBC, Hibernate, JPA, JDO)提供了统一的编程模式
2.为编程式事务提供了一个简单的API而非一系列复杂的事务API(如JTA)
3.支持声明式事务管理
4.可以和Spring的多种数据访问技术很好的融合
Spring常用的注解?
<!--在Spring的IOC容器中指定一个dao层的bean,如果value不指定默认该对象为id的类名,如果指定,id为value的值-->
@Repository(value = "userDao")
<!--依赖注入:-->
@Autowire: 默认为byType required:如果找不到bean注入ture(默认) 异常false: 不注入即可,不会报异常.
@Qualifier: 配合上面的注解使用,byName
@Resourse: javaEE提供的依赖注入的注解 1.6之后才可以使用
@Service("userService")
<!--将当前实体交给spring管理 等同于在IoC中配置了--><bean id="FirstController" class="包名.类名">
<!--value作用指定bean的id名称,如果不指定默认为类名,如果Controller中只配置value,可以省略value直接写值
表明当前是一个处理器-->
@Controller("userAction")
<!--action是多例模式,需要将scope设置为原型模式-->
@Scope("prototype")
<!--如果我们只是给前端返回json数据,并不进行页面的跳转,package就继承自json-default
要使用json-default包需要导入struts2的json插件(struts2-json-plugin-jar)-->
@ParentPackage("json-default")
@Namespace("/user")
<!--接收前端传递过来的数据-->
@ResponseBody
@Action(value = "updateUser", results = { @Result(name = "success", type = "json", params = { "root", "result" }) })
// 修改用户信息
public String updateUser() {
// System.out.println(user);
System.out.println("都是:" + user);
result = userService.updateUser(user);
System.out.println(result);
return SUCCESS;
}