黑马程序员技术交流社区

标题: 【石家庄校区】就业班_JavaEE_day43_46_Spring [打印本页]

作者: 风中的消逝    时间: 2018-7-6 09:53
标题: 【石家庄校区】就业班_JavaEE_day43_46_Spring
本帖最后由 小石姐姐 于 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>
            





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2