本帖最后由 小石姐姐 于 2018-7-31 10:37 编辑
就业班_JavaEE_day43_46_Spring
一 概述
一站式 IOC AOP Web JDBC Orm
二 主要内容
ioc di
aop
jdbctemplate
ssh整合
三 Ioc
工厂 + xml + 反射 来解耦合
beanfactory 根接口 applicationcontext 子接口 filesystemxmlapplicationcontext 实现类 classpathxmlapplicationcontext 实现类 webapplicationcontext 实现类
beanfactory特点 延迟加载 applicationcontext特点 立即加载 配置文件一加载则创建出对象
bean实例化的三种方式:
1无参数构造 采用第一种 <bean id="" class="">
2静态工厂
3实例工厂
四 di
依赖注入
1 set属性注入
基本类型和字符串 <property name="属性名称" value="属性值" />
引用类型 <property name="属性名称" ref="引用的bean" />
集合
属组和list
[Java] 纯文本查看 复制代码 <property>
<list>
<value></value>
</list>
</property>
set
<property>
<set>
<value></value>
</set>
</property>
map
<property>
<entity > </entity>
</property>
properties
<property>
<props>
<prop></prop>
<prop></prop>
</props>
</property>
2 有参构造注入
<constuct-arg>
3 p和c名称空间注入 简化属性和有参构造注入。
五 注解开发
用于类上
@component
@controller
@service
@Repository
@scope(singleton,prototype) singleton的bean在配置文件加载就创建,prototype的bean在getBean时才创建。
用于属性上
@autowired 默认按类型注入 是spring提供的注解
@qulifiey
@value
@resource 默认按名称注入 是jdk提供的注解 需要jdk1.6以上才支持
注解开发的配置
<!-- 组件扫描 --> 配置了组件扫描就包含了注解解析
<context:component-scan base-package="com.itheima.ssh"></context:component-scan>
<!-- 注解解析 -->
<context:annotation-config></context:annotation-config>
六 spring整合junit4
[Java] 纯文本查看 复制代码 ublic class MyAdvice implements MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor{
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("before");
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {
System.out.println("after");
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕前");
Object object = invocation.proceed();
System.out.println("环绕后");
return object;
}
}
七 springweb开发
[Java] 纯文本查看 复制代码 web.xml 添加ContextLoaderListener 和 contextConfigLocation
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
八 aop概述
面向切面编程
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中抽取出来,进行解耦.
九 aop相关术语
目标类 target
增强 advice 增强的功能实现
切入点 pointcut 被增强的方法
切面 aspect 增强+切入点
代理类 proxy
连接点jointpoint 可能被增强的方法
织入 是一个过程,表示通过切面将目标类增强获得代理类的过程。
十 aop的实现原理
AOP分为静态AOP和动态AOP。静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。
动态AOP是指将切面代码进行动态织入实现的AOP。
Spring的AOP为动态AOP,实现的技术为:JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术)
jdk:
Proxy.newProxyInstance(目标类的类加载器对象,目标类实现的接口class[] , invocationhandler接口的实现类 ,一般通过匿名类实现)
invocationhandler接口的invoke方法
invoke(Object proxy, Method method , Ojbect[] args){
//在方法前做一些操作
Object result = method.invoke(target,args);
//在方法后做一些操作
return result;
}
cglib:
Enhancer enhance = new Enhancer();// 1.创建Enhancer
enhance.setSuperclass(target.getClass());// 2.传递目标对象的Class
enhance.setCallback(MethodInterceptor接口的实现类);// 3.设置回调操作 (相当于InvocationHandler)
MethodInterceptor接口的方法
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methdoProxy) throws Throwable {
//在方法前做一些操作
return method.invoke(target, args); // 与jdk的proxy中操作类似
// return methdoProxy.invokeSuper(proxy, args); 该写法也可以实现,与上面的写法效果一样。
//在方法后做一些操作
}
return enhance.create();
十一aop的传统切面编程
有二种方式,一种是完全基于spring实现,一种是基于aspectj实现。二种实现方式的增强都需要实现接口.
p[AppleScript] 纯文本查看 复制代码 ublic class MyAdvice implements MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor{
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("before");
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {
System.out.println("after");
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("环绕前");
Object object = invocation.proceed();
System.out.println("环绕后");
return object;
}
}
1 传统AOP中增强方式
A. 前置通知 目标方法执行前增强 org.springframework.aop.MethodBeforeAdvice
B. 后置通知 目标方法执行后增强 org.springframework.aop.AfterReturningAdvice
C. 环绕通知 目标方法执行前后进行增强 org.aopalliance.intercept.MethodInterceptor
D. 异常抛出通知 目标方法抛出异常后的增强 org.springframework.aop.ThrowsAdvice
E. 引介通知 在目标类中添加一些新的方法或属性 org.springframework.aop.IntroductionInterceptor
2 完全基础sping的实现
[Java] 纯文本查看 复制代码 <!-- 目标对象target -->
<bean id="orderService" class="cn.itheima.aop.OrderServiceImpl"></bean>
<!-- 增强advice -->
<bean id="orderServiceAdvice" class="cn.itheima.aop.OrderHelper"></bean>
<!-- 切入点 pointcut -->
<bean id="orderServicePointCut" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames">
<list>
<value>add</value> //目标对象中的方法
<value>update</value>
</list>
</property>
</bean>
<!-- 切面aspect=pointcut+advice -->
<bean id="orderServiceAspect" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="orderServiceAdvice"/>
<property name="pointcut" ref="orderServicePointCut"/>
</bean>
<!-- 代理 proxy -->
<!--代理bean工厂 在IOC容器中存在二个目标类型的对象
<bean id="orderServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="orderService"/>
<property name="interceptorNames" value="orderServiceAspect"/>
</bean>
-->
<!-- 自动代理 在bean的生命周期过程中,完成代理 , 在IOC容器中只存在一个目标类型的对象 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
3.基于aspectj实现的传统切面
[Java] 纯文本查看 复制代码 <!-- 目标对象target -->
<bean id="target" class="com.itheima.service.UserServiceImpl"/>
<!-- 增强advice -->
<bean id="advice" class="com.itheima.advice.MyAdvice"/>
<!--完成自动代理-->
<aop:config>
<!--切入点-->
<aop:pointcut expression="execution(* com.itheima.service.UserServiceImpl.*(..))" id="pointcut1"/>
<!--切面-->
<aop:advisor advice-ref="advice" pointcut-ref="pointcut1"/>
</aop:config>
十二 aop的aspectj切面编程
有二种实现手段,一种是xml配置,一种是注解。二种实现手段的增强不用实现接口,普通的pojo.
[Java] 纯文本查看 复制代码 //before
public void before(){
System.out.println("MyAdvice2.before()");
}
//after
public void after(){
System.out.println("MyAdvice2.after()");
}
//around
public Object round(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前");
Object object = pjp.proceed();
System.out.println("环绕后");
return object;
}
aspectj切面编程的增强比传统的多一种最终通知.
1. 前置通知Before 相当于BeforeAdvice
2. 后置通知AfterReturning 相当于AfterReturningAdvice
3. 环绕通知 Around 相当于MethodInterceptor
4. 抛出通知AfterThrowing 相当于ThrowAdvice
5. 引介通知DeclareParents 相当于IntroductionInterceptor
6. 最终通知After 不管是否异常,该通知都会执行
XML实现
[Java] 纯文本查看 复制代码 <bean id="target" class="com.itheima.service.UserServiceImpl"/>
<bean id="advice" class="com.itheima.advice.MyAdvice2"/>
<aop:config>
<aop:aspect ref="advice">
<aop:pointcut expression="execution(* com.itheima.service.UserServiceImpl.*(..))" id="pointcut1"/>
<!-- <aop:before method="before" pointcut="execution(* com.itheima.service.UserServiceImpl.*(..))"/> -->
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="after" pointcut-ref="pointcut1"/>
<aop:around method="round" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
注解实现
[Java] 纯文本查看 复制代码 <bean id="target" class="com.itheima.service.UserServiceImpl"/>
<bean id="advice" class="com.itheima.advice.MyAdvice2"/>
<aop:config>
<aop:aspect ref="advice">
<aop:pointcut expression="execution(* com.itheima.service.UserServiceImpl.*(..))" id="pointcut1"/>
<!-- <aop:before method="before" pointcut="execution(* com.itheima.service.UserServiceImpl.*(..))"/> -->
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="after" pointcut-ref="pointcut1"/>
<aop:around method="round" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
十三 jdbctemplate
JdbcTemplate主要提供下列方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法(查询多行记录 ) 及queryForObject(查询一行记录)方法:用于执行查询相关语句;通过beanpropertymapping来封装记录
call方法:用于执行存储过程、函数相关语句。
spring提供jdbcdaosupport对jdbctemplate进行封装。通过继承jdbcdaosupport来实现dao。需要给到对象注入连接池对象。
十四 spring事务管理
优点:
1 对不同的事务管理(jdbc hbiernate jpa)提供统一的API管理
2 支持声明式事务管理(采用基于spring的切面)
统一的api:三个接口
PlatformTransactionManager 事务管理器 针对不同的dao层技术有响应的实现类
DataSourceTransactionManager 主要针对于JdbcTemplate开发 MyBatis开发
HibernateTransactionManasger主要针对于Hibernate开发
JpaTransactionManager 主要针对于JPA开发。
TransactionDefinition 定义事务的特征
隔离 定义隔离级别 默认隔离级别是default 采用数据库原有的隔离级别
传播 主要关注三种。
required 默认为该值,表示不同的方法采用共用一个事务
requirednew 表示针对不同的方法开启不同的事务
nected 只能对datasourcetransacitonmangage有效。可以回滚到制定的savepoint
超时
只读 默认为false 即事务中可以有update delete insert操作,如果设置为true 则只能做select操作
TransactionStatus
表示事务运行过程中的某个时间点的状态
申明式事务二种实现方式:
1 xml
引入属性文件
[Java] 纯文本查看 复制代码 <datasource> ${}
<dao> 注入DataSource 继承jdbcdaosupport
<service> 注入dao
<transactionmanage datasourcetransactionmanager> 注入datasource
<tx:advice 引入事务管理器>
<tx:attribute>
制定增强作用于那些方法 method 在这里可以指定事务的特征
</tx:attribute>
</tx:advice>
<aop-config>
<aop:pointcut id = 表达式>
<aop:advisor pointcutref adviceref>
</aop-config>
2 注解
<datasource> ${}
<dao> 注入DataSource 继承jdbcdaosupport
<service> 注入dao
<transactionmanage datasourcetransactionmanager> 注入datasource
<tx:annotation-driven 指定事务管理器>
在service上
添加@transaciton 在这里可以指定事务的特性。
十五 ssh整合
1 jar包
struts2
spring
hibernate
2 配置文件
struts.xml
applicationContext.xml
db.properties
log4j.properties
3 spring整合hibernate
第一种 保留hibernate.cfg.xml
第二种 不保留hibernate.cfg.xml 全部写在applicacationContext.xml中
4 spring 整合struts
需要添加整合包struts2-spring-plugin.jar
默认struts中的action interceptor result 等对象是根据自身的objectfactory来创建的
<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
一旦导入plugin包之后
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.objectFactory" value="spring" />
将有spring来管理action interceptor result 对象的创建。
spring整合struts2框架它的方式有两种
1.spring管理action(在applicationContext.xml文件中声明action)
action中的class 写applicationcontext中actionbean的名字
2.action自动装配service
action中的class 写全路径名,action对象将有spring通过反射创建,并自动注入service对象。
5 二种整合方式的配置
xml方式
[Java] 纯文本查看 复制代码 applicationContext.xml
<!-- 加载数据库连接四要素 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置c30数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}" />
<property name="jdbcUrl" value="${jdbcUrl}" />
<property name="user" value="${user}" />
<property name="password" value="${password}" />
</bean>
<!-- 配置hibernate的sessionfactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 映射文件是xml时,通过制定映射文件的目录位置来加载-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:com/itheima/mavenweb/domain</value>
</list>
</property>
</bean>
<!-- 配置事务管理器 使用hibernate -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--配置事务的增强 -->
<tx:advice transaction-manager="transactionManager" id="advice1">
<tx:attributes>
<tx:method name="findAll"/>
</tx:attributes>
</tx:advice>
<!--配置事务的切面 -->
<aop:config>
<aop:pointcut expression="execution(* com.itheima.mavenweb.service.impl.UserServiceImpl.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="advice1" pointcut-ref="pointcut1"/>
</aop:config>
<!--配置dao注入sessionfactory -->
<bean id="userDao" class="com.itheima.mavenweb.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="userService" class="com.itheima.mavenweb.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
<bean id="userAction" class="com.itheima.mavenweb.web.action.UserAction">
<property name="userService" ref="userService" />
</bean>
struts.xml
<package name="base" namespace="/" extends="struts-default">
<action name="user_*" class="userAction" method="{1}"> //action中的class是伪类,是在applicationcontext中的配置的actionID
<result name="list">/list.jsp</result>
</action>
</package>
注解方式 注解方式要添加相应的jar包
a[Java] 纯文本查看 复制代码 pplicationContext.xml
<!-- 加载数据库连接四要素 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置c30数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}" />
<property name="jdbcUrl" value="${jdbcUrl}" />
<property name="user" value="${user}" />
<property name="password" value="${password}" />
</bean>
<!-- 配置hibernate的sessionfactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 映射关系是注解时,通过制定扫描的package来指定class-->
<property name="packagesToScan">
<list>
<value>com.itheima.domain</value>
</list>
</property>
</bean>
<!-- 配置事务管理器 使用hibernate -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 开启事务注解 -->
<tx:annotation-driven/>
<!-- 组件扫描 -->
<context:component-scan base-package="com.itheima.ssh"></context:component-scan>
|