一直不能坐下来好好学习一下, 最近研究了spring framework, 一点感受:
1. ioc
传统方法:如果动态设置一个对象属性,可以借助java的reflection机制完成,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标签接口。 取出就可使用的通知有 methodinterceptor、 throwsadvice、 beforeadvice和 afterreturningadvice。
也可以自己写个拦截器,在实现自己的方法之前出发某个动作,执行一些处理。
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得启动要稍微延迟一些,如果在这时要做一些业务的操作,启动的前后顺序是有影响的。
那么在contextloaderlistener和contextloaderservlet中到底做了什么呢?
以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是把webapplicationcontext(xmlwebapplicationcontext是默认实现类)放在了servletcontext中,servletcontext也是一个“容器”,也是一个类似map的结构,而webapplicationcontext在servletcontext中的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.xml中action的配置变成类似下面的样子
<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>
-
关于我们
公司介绍 最新动态 联系我们 -
产品与服务
域名注册 jsp空间 php空间 -
常见问题
空间操作手册 网站备案相关 退款相关问题 -
技术支持
技术 QQ :178966803 联系电话:13616026886 联系邮箱:fjjsp@vip.163.com
扫描关注微信公众号
闽公网安备 35060202000074号