打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
spring阶段性的一点感受
 

一直不能坐下来好好学习一下, 最近研究了spring framework, 一点感受:

1. IOC

传统方法:如果动态设置一个对象属性,可以借助JavaReflection机制完成,invoke()激活返回调用

Class cls = Class.forName("com.eking.User");

Method mtd = cls.getMethod("setName",new Class[]{String.class});

Object obj = (Object)cls.newInstance();

mtd.invoke(obj,new Object[]{"Erica"});

return obj;

        在spring中, 面向接口编程,动态代理机制:BeanWrapper, BeanFactory,ApplicationContext提供了管理javabean的包装器,所有的一切都在容器中配置,dependency injection.

也可以不提供接口,CGLib与Dynamic Proxy的代理机制基本类似,只是其动态生成的代理对象并非某接口的实现,而是针对目标类扩展的子类。换句话说,Dynamic Proxy返回的动态代理类,是目标类所实现的接口的另一个实版本,它实现了对目标类的代理(如同UserDAOProxy与UserDAOImp的关系)。而CGLib返回的动态代理类,则是目标代理类的一个子类(代理类扩展了UserDAOImp类)。

2. AOP

   各种通知类型有MethodInterceptor (来自AOP联盟的拦截器API)和定义在org.springframework.aop包中的 通知接口。所有通知必须实现org.aopalliance.aop.Advice标签接口。 取出就可使用的通知有 MethodInterceptorThrowsAdviceBeforeAdviceAfterReturningAdvice

    也可以自己写个拦截器,在实现自己的方法之前出发某个动作,执行一些处理。

3. WebApplicationContext

1)  web.xml 中通过声明监听器接口 servlet类加载
通过: 
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener-->
或:
   <servlet>
      <servlet-name>SpringContextServlet</servlet-name>
      <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
Web
容器会自动加载 /WEB-INF/applicationContext.xml 初始化 ApplicationContex t实例;
也可以通过
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext-*.xml</param-value>
   </context-param>
使 Web 容器加载指定名称路径的 Spring 配置文件。

我个人认为Listerner要比Servlet更好一些,因为Listerner监听应用的启动和结束,而Servlet得启动要稍微延迟一些,如果在这时要做一些业务的操作,启动的前后顺序是有影响的。

那么在ContextLoaderListenerContextLoaderServlet中到底做了什么呢?
ContextLoaderListener为例,我们可以看到
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
protected ContextLoader createContextLoader() {
return new ContextLoader();
}
        ContextLoader
是一个工具类,用来初始化WebApplicationContext,其主要方法就是initWebApplicationContext,我们继续追踪initWebApplicationContext这个方法(具体代码我不贴出,大家可以看Spring中的源码),我们发现,原来ContextLoader是把WebApplicationContextXmlWebApplicationContext是默认实现类)放在了ServletContext中,ServletContext也是一个“容器”,也是一个类似Map的结构,而WebApplicationContextServletContext中的KEY就是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE我们如果要使用WebApplicationContext则需要从ServletContext取出,Spring提供了一WebApplicationContextUtils类,可以方便的取出WebApplicationContext,只要把ServletContext传入就可以了。

2) struts-config.xml 中通过插件加载
通过
    <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
        <set-property property="contextConfigLocation"
            value="/WEB-INF/applicationContext.xml,
                   /WEB-INF/action-servlet.xml"/>
    </plug-in>
来加载 Spring 配置文件。

struts-config.xmlAction的配置变成类似下面的样子
<action attribute="aForm" name="aForm" path="/aAction" scope="request" type="org.springframework.web.struts.DelegatingActionProxy">
<forward name="forward" path="forward.jsp" />
</action>

别急,我们还是来看一下ContextLoaderPlugIn的源码(源码不再贴出),我们可以发现,原来ContextLoaderPlugIn仍然是把WebApplicationContext放在ServletContext中,只是这个KEY不太一样了,这个KEY值为ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX+ModuleConfig.getPrefix()(具体请查看源代码),这下好了,我们知道了WebApplicationContext放在哪里,只要我们在Web应用中能够取到ServletContext也就能取到WebApplicationContext

4.Struts+spring+hibernate

spring live中myusers,一个3层架构的web 程序,通过一个Action 来调用业务代理,再通过它来回调 DAO类。下面的流程图表示了MyUsers是如何工作的。数字表明了流程的先后顺序,从web层(UserAction)到中间层(UserManager),再到数据层(UserDAO),然后返回。

Spring是AOP, UserManager和UserDAO都是接口.

1)    web层(UserAction) :调用中间层的接口方法,将UserManager作为属性注入

2)     中间层(UserManager):将UserDAO作为属性注入,其实现主要是调用数据层接口的一些方法; 它处于事务控制中

3)     数据层(UserDAO):实现类继承HibernateDaoSupport类,在该类中可以调用getHibernateTemplate()的一些方法执行具体的数据操作。

spring配置部分文件:

<bean id="userDAO" class="com.eking.entity.UserDAOImp">

            <property name="sessionFactory">

                <ref local="sessionFactory" />

            </property>

        </bean>

      

       <bean id="userManagerTarget" class="com.eking.service.UserManagerImp">

             <property name="userDAO"><ref local="userDAO"/></property>

       </bean>

   

       <bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

            <property name="transactionManager">

                 <ref local="transactionManager" />

            </property>

            <property name="target">

                 <ref local="userManagerTarget" />

            </property>

            <property name="transactionAttributes">

                 <props>

                      <prop key="insert*">PROPAGATION_REQUIRED</prop>

                      <prop key="get*">PROPAGATION_REQUIRED</prop>

                      <prop key="is*">PROPAGATION_REQUIRED</prop>

                  </props>

            </property>

       </bean>

      

       <bean name="/login" class="com.eking.struts.action.LoginAction" singleton="false">

            <property name="userManager">

                 <ref local="userManager" />

           </property>

      </bean>


spring live中myusers,一个3层架构的web 程序,通过一个Action 来调用业务代理,再通过它来回调 DAO类。下面的流程图表示了MyUsers是如何工作的。数字表明了流程的先后顺序,从web层(UserAction)到中间层(UserManager),再到数据层(UserDAO),然后返回。

Spring是AOP, UserManager和UserDAO都是接口.

1)    web层(UserAction) :调用中间层的接口方法,将UserManager作为属性注入

2)     中间层(UserManager):将UserDAO作为属性注入,其实现主要是调用数据层接口的一些方法; 它处于事务控制中

3)     数据层(UserDAO):实现类继承HibernateDaoSupport类,在该类中可以调用getHibernateTemplate()的一些方法执行具体的数据操作。

spring配置部分文件:

<bean id="userDAO" class="com.eking.entity.UserDAOImp">

            <property name="sessionFactory">

                <ref local="sessionFactory" />

            </property>

        </bean>

      

       <bean id="userManagerTarget" class="com.eking.service.UserManagerImp">

             <property name="userDAO"><ref local="userDAO"/></property>

       </bean>

   

       <bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

            <property name="transactionManager">

                 <ref local="transactionManager" />

            </property>

            <property name="target">

                 <ref local="userManagerTarget" />

            </property>

            <property name="transactionAttributes">

                 <props>

                      <prop key="insert*">PROPAGATION_REQUIRED</prop>

                      <prop key="get*">PROPAGATION_REQUIRED</prop>

                      <prop key="is*">PROPAGATION_REQUIRED</prop>

                  </props>

            </property>

       </bean>

      

       <bean name="/login" class="com.eking.struts.action.LoginAction" singleton="false">

            <property name="userManager">

                 <ref local="userManager" />

           </property>

      </bean>

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何运用spring的autowire为servlet注入Bean(转自网路) - 让自己...
spring hibernate的事务处理(使用hibernate原有的sessionFactory)
yanghuw的专栏,第一个Spring程序
Spring mvc 3.0 怎么配置velocity tools (dateTool/n...
SpringMVC源码分析——初始化过程
Spring3.2.4 和 MyBatis 整合笔记
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服