好尴尬,发现自己写上篇技术博文,已经是一年前的事情了,好像把时间都浪费在娱乐上了?没有吧,工作还是很认真的。业余时间,是有点浪费了,不过还是有研究过一些精彩的东东来分享的。不说闲话了,这就分享出来。
这段时间里还是一直对新型的几个主流的Java框架做一些研究,现在以一个 Web Application 的模型 将笔者的心得课题化并一一分享出来。今天是第一篇,分享下笔者对一个小型Web程序的架构,以及如何将原来的web.xml和spring的applicationContext.xml对应到新型注解化的配置类中。
之前《究 Spring 3.1之无web.xml式 基于代码配置的servlet3.0应用》中已经将知晓了Spring是如何利用Servlet3中的ServletContainerInitializer进行Web初始化配置的,这里笔者就不再自己去写了,像利用Spring的FileCopyUtils一样,清楚它是怎么实现的就好,用时直接拿来用,方便。
架构如图所示。src包中,分层为三
1,控制层ctrl,MVC的C大家都知道,表层,与UI的数据调度,接收Http请求并做出相应响应,这里还未确定具体用什么框架,先放着。
2,业务层hub,叫biz, business, service都行,即业务逻辑层,整个web核心调度层。
3 外部层pin,通常是dao数据访问层,然后自我认为这里不单单会借助数据库做为外部辅助系统,与外部其他系统都应该放在这层里,做为与外部系统沟通的底层,所以用了个很形象的 针脚pin 一词。
所谓的外部系统还有可能是邮件服务器,webService调用与被调用,等等,甚至是文件资源。比方说,文件资源有时不一定会存储在部署的服务器上,也有可能外包于其它专门的服务器,例如amazon的S3, 这时,业务层hub无需要知道文件资源的存储是何策略,直接调用底层的方法,由pin层的专门管理文件资源存储的类去具体操作。再往下面的persistence 做传统意义的dao服务。
当然别忘了entity, 就是业务实体模型。
Util 里放一些配置,工具等的类 。例如图中选中的高亮文件,就是对应于以往web.xml的文件,这里命名其为WebConfiguration, 当然,名字因人而异。
测试包testsrc在后面的 单元测试一节会具体说明,这里就过了。
然后用到的库,JRE不多说,Web App Lib是将所需的jar文件放到WebContent/WEB-INF/lib下后自动生成的。
测试库SpringJunit4也是测试章节的。后面的运行时库是为了做servlet包的,随便加一个有servlet3支持的就好。
WebContent下的内容是之后部署环境的所有内容,笔者这里放着个sysParams.properties就是系统的一些配置属性,部署人员做web部署时,只需要改这一个就行。开发过程中有可配置的选项都应该通过一个静态的Properties类对象去找到相应的名值对,通过一定方法转换为所需类型。至于怎么实现,这就来看。
首先来着,对应于原来web.xml的WebConfiguration代码如下:
package com.gxino.webmodel.util;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
public class WebConfiguration implements WebApplicationInitializer{
private static Properties sysParams=new Properties();
public static Properties getSysParams() {
return sysParams;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
try {
String sysParamsLocation=this.getClass().getResource("/").getFile().replace("/classes/", "/sysParams.properties");
sysParams.load(new FileReader(sysParamsLocation));
} catch (IOException e) {
}
AnnotationConfigWebApplicationContext annoAppCtx
= new AnnotationConfigWebApplicationContext();
annoAppCtx.register(ApplicationContext.class);
if(servletContext!=null)servletContext.addListener(new ContextLoaderListener(annoAppCtx));
}
}
它实现Spring的WebApplicationInitializer后写了方法onStartup(servletContenxt), 因为支持servlet3的服务器启动后会找到WebApplicationInitializer的所有实现类并执行其onStartup方法,至于想了解它如何做到的,文章开头已经说明,请去阅读另一篇博文。 在这个方法里,笔者首先做的是load sysParams.propertyies文件到本类的一个静态Properties变量sysParams中,这样一来,任何一处代码都可以直接get到这个sysParams。 之后的两句代码是建立一个
WebApplicationCotext,自然就是Spring的东西了,意思很明显,注解配置化的WebApplication环境,这个环境的配置在哪? 就是ApplicationContext.class,将它注册到上面的环境中。最后一句servletContext.addListener,就是以往配置的
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
用以启动Spring。当然servletContext其实就是application, 它可以add servlet, listener, filter, servlet param, 也就是说,可以做任何 web.xml的配置。不过其实我们要写这些类时,直接去实现 WebApplicationInitializer 并在里面写了onStartup方法就行,同样会在服务器启动时就被执行,关于这点,之前的无博文也有说明。
下面将关注点放在上面提到的配置类ApplicationContext.class,笔者将它命名如此,正是为了展示它就是以往的applicationContext.xml。
package com.gxino.webmodel.util;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate3.HibernateInterceptor;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import com.gxino.webmodel.entity.AccountEntity;
import com.gxino.webmodel.entity.ActionLogEntity;
@Configuration
@ComponentScan("com.xxxx.webmodel")
public class ApplicationContext {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Bean(destroyMethod = "close")
public DataSource dbcpDataSource() {
Properties parameters = WebConfiguration.getSysParams();
BasicDataSource basicDS = new BasicDataSource();
basicDS.setDriverClassName(parameters.getProperty("jdbc.driver",
"oracle.jdbc.OracleDriver"));
basicDS.setUrl(parameters.getProperty("jdbc.url",
"jdbc:oracle:thin:@localhost:1521:xe"));
basicDS.setUsername(parameters.getProperty("jdbc.username", "system"));
basicDS.setPassword(parameters.getProperty("jdbc.password",
"oraclesystem"));
basicDS.setMaxIdle(1000);
basicDS.setMinIdle(4);
basicDS.setMaxActive(8);
basicDS.setInitialSize(3);
basicDS.setMaxWait(10000);
return basicDS;
}
@Configuration
static class SessionFactoryConfig {
@Resource
private DataSource ds;
public DataSource getDs() {
return ds;
}
public void setDs(DataSource ds) {
this.ds = ds;
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean asfBean = new LocalSessionFactoryBean();
asfBean.setDataSource(this.getDs());
Properties parameters = WebConfiguration.getSysParams();
Properties prop = new Properties();
prop.setProperty("hibernate.dialect", parameters.getProperty(
"hibernate.dialect", "org.hibernate.dialect.OracleDialect"));
prop.setProperty("hibernate.connection.autocommit", parameters
.getProperty("hibernate.connection.autocommit", "false"));
prop.setProperty("hibernate.show_sql",
parameters.getProperty("hibernate.show_sql", "true"));
prop.setProperty("hibernate.hbm2ddl.auto",
parameters.getProperty("hibernate.hbm2ddl.auto", "update"));
asfBean.setHibernateProperties(prop);
@SuppressWarnings("rawtypes")
Class[] entities = new Class[2];
entities[0] = AccountEntity.class;
entities[1] = ActionLogEntity.class;
asfBean.setAnnotatedClasses(entities);
return asfBean;
}
}
@Bean
public HibernateTransactionManager hibernateTransactionManager() {
HibernateTransactionManager hiberTransMana = new HibernateTransactionManager();
hiberTransMana.setSessionFactory(this.getSessionFactory());
return hiberTransMana;
}
@Bean
public HibernateInterceptor hibernateInterceptor() {
HibernateInterceptor hiberInter = new HibernateInterceptor();
hiberInter.setSessionFactory(this.getSessionFactory());
return hiberInter;
}
@Bean
public HibernateTemplate hibernateTemplate() {
HibernateTemplate hiberTempl = new HibernateTemplate();
hiberTempl.setSessionFactory(this.getSessionFactory());
return hiberTempl;
}
}
好,一点一点理解这个ApplicationContext的代码.
首先,applicationContex.xml是<beans>包裹着的各种<bean>, 这里被@Configuration注解的一个class ApplicationContext总体就可以看作是<beans>, 其实@Configuration本身就是个bean, 去看它的代码就知道,它被@Component注解,我们可以理解它为 配置bean。然后这个ApplicationContext中有很多被@Bean注解的方法,就是在这个配置bean中配置的Bean以供程序注入使用。这些方法的返回值是bean的class类型,方法名是bean的name, 即我们xml中配置的<bean class=”” name=””>, 在方法体中,对该bean进行配置。为下文的方便理解,总结一点,配置bean的格式为: @Configuration注解的类称为 配置bean类型,其中有很多@Bean注解的方法,用这些方法中的代码配置中一个类实例以供注入准备。
继续,应该看到该类里还有@Configuration注解的静态类,格式如同类ApplicationContext, 再啰嗦一遍:@Configuration注解的配置类中有一或多个@Bean注解的方法。 这是干什么用的?想象一下我们在xml中配置这个SesstionFactory, 需要用到一个ref将配置好的dataSource 注入进来,那么到了代码的方式怎么办?其实再熟悉不过了,定义一个类注册为Spring的bean类型,并用声明一个类成员变量,用@Resource将它注入进来。 OK, 到这儿有两个问题,这个内置的配置bean为什么是静态的?还有没有别的方法去配这种需要ref其它bean的bean?留给读者思考一下。
总结一句话, 其实体会一下就会理解,@Configuration注解的class是一种配置bean的声明, 将会被Spring代理实例化作为特殊的bean去用,@bean注解的方法中,我们会去实例化一个类,并返回出来,很大的可能Spring会用BeanType bean ={调用@Bean注解的会返回BeanType实例的方法} 的形式来生成一个bean实例, 然后用一个诸如Map等方式储存这个bean到它的Context中,以便注入到其它bean中。
别忘记看@ComponentScan("com.xxxxx.webmodel"), 它的意思是寻找类路径为com.xxx.webmodel的bean类的声明,类似于<context:component-scan base-package="com.foo.bar"/>(这个需要xml命名空间) 。即是说寻找我们自定义的bean类型,那么我们需要用@Component及其子注解类型如@Controller,@Service, @Repository注解一些com.xxxx.webmodel为类路径开头的类来让spring找到并代理生成bean实例。也就是用Spring的主旨,让它来托管我们的业务类实例。
第一篇就分享到这里。
分享到:
相关推荐
Java EE Web Application Primer Building Bullhorn A Messaging App with JSP, Servlets, JavaScript, Bootstrap and Oracle 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请...
Build a Twitter-like web application called Bullhorn using Java, Oracle, and more Create web applications using Eclipse Design web pages with HTML forms, tables, and more Use SQL along with Java ...
Digital Java EE 7 Web Application Development 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Prepare for the Pivotal Certified Spring Web Application Developer exam and learn about Spring MVC DispatcherServlet configuration, Spring MVC programming model essentials, Spring MVC views and form ...
Java EE Web Application Primer Building Bullhorn A Messaging App with JSP, Servlets, JavaScript, Bootstrap and Oracle 英文无水印原版pdf pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和...
用java开发Arcgis server 9.2 web application
Tomcat Administration Web Application使用配置
Encapsulating security requirements for web development with the Java programming platform, Secure Java: For Web Application Development covers secure programming, risk assessment, and threat ...
信息: Deploying web application directory lx01 2010-11-11 22:52:05 org.apache.catalina.startup.HostConfig deployDirectory 信息: Deploying web application directory blog 2010-11-11 22:52:06 org.apache....
WebApplication1.zip
Web压力测试工具 web application stress tool 1.1
NULL 博文链接:https://panyongzheng.iteye.com/blog/1637889
本文介绍Microsoft的Web Application Stress Tool(WAS,Web应用负载测试工具)在Web服务器性能测试中的应用(注:Stress基本含义为“重压;压力”等,本文称之为“负载”)。另 外,我们还将通过WAS评估一种相对...
有关JavaApplet和JavaApplication一些介绍
Web Application Design
Ext.NET Web Application DevelopmentExt.NET Web Application DevelopmentExt.NET Web Application DevelopmentExt.NET Web Application DevelopmentExt.NET Web Application DevelopmentExt.NET Web Application ...
2)AngularJS非常全面,没有其它的插件或者架构足以开发数据驱动的web应用;3)开发过程简单快捷。 内容推荐 AngularJS诞生于Google,已用于开发多款Google产品。它是一套JavaScript前端框架,用于开发当下流行的...
Web Application Stress Tool,微软官方的.web压力测试工具