jboss之启动加载过程详解
-
今天看了看jboss的boot.log和server.log日志,结合自己的理解和其他的资料,现对jboss的启动和加载过程做出如下总结;
boot.xml是服务器的启动过程的日志,不涉及后续的操作过程
server.xml是操作过程的日志,比如部署文件,加载资源等等,是更加详细的,其中包含了启动的过程
本文以JBoss Application Server 4.2.1 GA(以下简称JBoss)为例,介绍它在Windows平台上的启动过程。为了方便叙述,对平台环境做以下假定:Java运行时的安装路径为C:/Java,JBoss的安装路径为C:/JBoss。
既然用100% Java编写的JBoss具有跨平台的特性,那为什么还要强调Windows平台呢?这是因为,JBoss的启动是从平台相关的脚本文件开始的,而在不同 平台上的脚本文件是不同的。例如,Window平台上的脚本文件是run.bat,linux平台上的脚本是run.sh。两个文件的内容有很大不同,功 能也许差不多,无非是配置启动环境,但是也有可能存在平台相关的因素。我只看了run.bat,对run.sh并不了解,为谨慎起见,我只介绍 run.bat,对run.sh不作阐述。
在介绍JBoss启动过程之前,我想先介绍一下JBoss的结构特征,这将有利于大家理解启动过程。JBoss基于JMX框架,它的结构就是一个 MBeanSserver以及一些挂在MBeanServer上的MBean。MBean提供功能,MBeanServer是MBean之间的通信总线。 JMX框架的好处就是给JBoss带来了高度的灵活性、可配置性。可配置性也是JBoss的核心理念之一,几乎所有的JBoss部件都可以被替换。 JBoss通过系统属性、配置文件等多种方法,帮助实现高度的可配置性。我们可以通过设置系统属性,或者通过编辑配置文件,来定制自己的JBoss版本。这种可配置性体现在JBoss的各个角落,启动过程只能窥一斑,若欲知全豹,可以研究一下JBoss的EJB容器等其它部件。
介绍完JBoss的结构特征,我们开始进入JBoss的启动过程。整个过程可以分为六个阶段,下面将依次介绍。
一、执行启动脚本,配置启动环境
JBoss的启动过程从执行run.bat开始,run.bat的主要工作就是配置启动环境。
JBoss的启动环境其实是一些启动参数,例如JBoss的安装路径、java命令的参数、JBoss的类路径等。
如果在配置过程中发生错误,run.bat的执行将被中断。
run.bat将配置以下启动参数:
JBOSS_HOME
JBoss的安装路径,其值为C:/JBoss
PATH
将C:/JBoss/bin/native添加到PATH中,native下的文件是平台相关的,可以优化JBoss的性能。
JAVA
java.exe文件的路径,其值为C:/Java/bin/java
JAVA_OPTSB
java命令的参数,其值为-Dprogram.name=run.bat –server-Xms128m –Xmx512m –Dsun.rmi.dgc.client.gcInterval=3600000 –Dsun.rmi.dgc.server.gcInterval=3600000
JBOSS_CLASSPATH
JBoss的启动类路径,其值为C:/Java/lib/tools.jar;C:/JBoss/bin/run.jar。JBoss的启动前期需要的类文件都在这两个jar中。
如果没有设置系统环境变量JAVA_HOME,那么run.bat的执行将被中断,JBoss启动失败。因此,在安装好JBoss后,一定要设
置JAVA_HOME系统环境变量。
如果run.bat执行顺利,那么在最后,将会执行以下命令:
C:/Java/bin/java -Dprogram.name=run.bat –server-Xms128m –Xmx512m –Dsun.rmi.dgc.
client.gcInterval=3600000 –Dsun.rmi.dgc.client.gcInterval=3600000 -Djava.endorsed.dirs=
C:/JBoss/lib/endorsed –classpath C:/Java/lib/tools.jar;C:/JBoss/bin/run.jar org.jboss.Main/%*
%*代表run.bat后面的启动参数。
从这条命令开始,真正运行JBoss的代码。
二、JBoss启动的入口
JBoss的魔术从Main.main方法开始。Main这个类位于run.jar中。Main.main方法创建了一个名为”jboss”的线程 组,然后创建并运行该线程组的线程”main”。”main”线程开始运行后,Main.main方法执行完毕,主线程也随之结束。”main”线程的主 要工作是调用Main.boot方法。
Main.boot方法的主要工作是处理命令行参数,然后创建并运行一个服务器实例。当服务器实例开始运行后,jboss的启动过程也就成功结束了。下面的几个阶段都是boot方法的执行过程。
三、处理命令行参数
boot方法调用Main.processCommandLine方法,来处理命令行参数。这里的命令行参数其实就是main方法的args参数,它作为实参传递给processCommandLine方法。
processCommandLine方法使用了GNU-getopt程序包来解析命令行参数,对不同的命令行参数有不同的处理方式,简单概括如下:
部分参数被简单处理后,程序直接退出。
processCommandLine方法执行完毕后,boot方法将加载、创建并运行一个服务器实例。
四、加载并创建服务器实例
服务器实例是一个运行时对象,这个对象代表了运行着的JBoss应用服务器。启动一个JBoss应用服务器,就会有一个服务器实例与
之对应。在JBoss中,服务器实例的实现是可以配置的,也就是说,服务器类不是固化的,而是可以替换的。这就带来一个问题:
JBoss必须在启动的过程中搜索并加载服务器类。
搜索并加载服务器实例类的工作由一个辅助类完成,它的全限定类名是org.jboss.system.server.ServerLoader。这个类会创建
一个特定的类加载器,并使用这个类加载器加载服务器类,然后利用反射机制,创建一个服务器实例。
boot方法首先创建一个ServerLoader实例,我们把它称为loader,然后boot方法将一些url添加到loader中。我们把这些url称为
服务器搜索路径。loader就是在服务器搜索路径中搜索服务器类。
loader自带的url log4j-boot.jar、jboss-common.jar、jboss-system.jar、jboss-xml-binding.jar。
添加完服务器搜索路径后,boot方法调用了loader的load方法。load方法以服务器搜索路径作为参数,创建一个类加载器,并使用
它搜索和加载服务器类。如果成功加载,就利用放射机制,创建一个服务器实例,我们把它称为server。
默认的服务器类是org.jboss.system.server.ServerImpl,它位于C:/JBoss/lib/jboss-system.jar中,并不在jboss的类路径
中。因此,loader必须创建自己的类加载器,使用服务器搜索路径作为类搜索路径,才能够找到ServerImpl。通过设置
jboss.server.type系统属性,也可以使用自定义的服务器类。当然,前提是要保证自定义的服务器类的类文件要在服务器搜索路
径中。
服务器实例创建完毕后,还需要对它进行配置,这就是下面的初始化工作。
五、初始化服务器实例
初始化服务器实例的主要工作就是将服务器配置信息封装到一个对象中。这个对象是类
org.jboss.system.server.ServerConfigImpl的实例,如org.jboss.system.server.ServerConfigImpl@8b33e8。它包括了服务器实例的基本配置信息,例如JBoss的安装路径、服务器的根
目录、服务器的日志目录、服务器的临时目录、服务器的库路径等。
boot方法调用server的init方法,开始初始化工作。Init方法将初始化工作委派给server..doInit方法。doInit方法创建并配置ServerConfigImpl对象,并在最后在控制台和日志中打印出服务器的配置信息。
ServerConfigImpl对象是一个MBean,因此,用户可以利用jmx控制台查看服务器实例的配置信息。
初始化完毕后,就要启动服务器实例了。
六、启动服务器实例
启动服务器实例是一个复杂的过程,其中有很多的工作需要完成。前面已经提到,JBoss是基于JMX框架的,JBoss的主要功能都是
以MBean的形式作为服务提供的,服务之间利用JMX总线进行通信。直到目前为止,我们还没有看到JMX相关的工作。因此,在服务
器实例的启动过程中,首要的工作就是要搭建JMX框架。JMX框架搭建完毕后,JBoss需要创建几个基本的服务,这些服务正是以
MBean的形式,挂在JMX框架上。之后,JBoss开始了部署过程。JBoss预配置的服务、用户的部署单元都在这个阶段被部署、启动。
boot方法调用server.start方法,开始了启动过程。start方法将启动工作委派给了server.doStart方法。doStart方法依次完成以
下工作:
1.创建并启动计时器
这个计时器是用来计算JBoss启动的时间,JBoss启动成功后,会在控制台输出启动过程所耗的时间,背后的秘密就在这里。(这个
无关紧要,为了完整性介绍一下)。
2.创建MBeanServer实例
MBeanServer是JMX框架的核心。JBoss需要创建一个MBeanServer实例。,MBeanServer的实现也是可以配置的。目前可以
使用两种MBeanServer,一种是jvm platform MBeanServer,它是Java平台提供的;另一种是JBoss提供的,全限定类名为
org.jboss.mx.server.MBeanServerImpl。通过设置javax.management.builder.initial系统属性,也可以使用自定义
MBeanServer。那么JBoss究竟使用的是哪种实现呢?如果Java版本达到或高于5.0,且jboss.platform.mbeanserver系统属
为true,则使用jvm platform MBeanServer,否则都使用JBoss提供的MBeanServerImpl。(这一点说得并不准确,涉及
LazyMBeanServer,我还不太清除。大家可以认为,绝大部分情况下,都是用JBoss提供的MBeanServerImpl)。
3. 创建并注册基础服务
在创建MBeanServerImpl的过程中,会创建以下3个MBean:
第一个MBean是javax.management.MBeanServerDelegate, ObjectName=JMImplementation:type=MBeanServerDelegate
第二个MBean是一个动态MBean,org.jboss.mx.modelmbean.XMBean,ObjectName=JMImplementation:type=MBeanRegistry
第三个MBean是org.jboss.mx.loading.UnifiedLoaderRepository3,
ObjectName=JMImplementation:service=LoaderRepository, name=Default
第一个MBean是在调用MBeanServerImpl之前创建的,后面两个MBean实在MBeanServerImpl的构造函数中创建的。 第二个MBean是用来MBeanServer的注册表,所有挂在MBeanServer上的MBean都被注册到注册表中。第三个MBean与 JBoss的类加载架构有关,也是基础服务之一。
服务器server和ServerConfigImpl也都是MBean,也都被注册到MBeanServer,ObjectName分别为jboss.system:type=Server和jboss.system:type=ServerConfig。
然后,doStart方法创建并注册以下3个MBean:
第一个MBean是org.jboss.system.server.ServerInfo,
ObjectName= jboss.system:type=ServerInfo
第二个MBean是org.jboss.system.ServiceController,
ObjectName= jboss.system:service=ServiceController
第三个MBean是org.jboss.deployment.MainDeployer,
ObjectName= jboss.system:service=MainDeployer
第一个MBean主要封装了JBoss运行的软硬件平台的信息,包括主机地址、J操作系统版本、Java版本等。
第二个MBean是用来控制MBean的生命周期。JMX规范没有规定
引自博文:http://www.2cto.com/os/201404/293620.html
查看JBoss控制台JMX-Console
//可以通过这个页面进行对 JBOSS 的各服务的配置和管理。
http://localhost:8080/jmx-console/
查看发布的WebService(进入 JbossWS 的查看界面)
http://localhost:8080/jbossws/
1.WAR文件的部署
JBoss支持热部署,也就是war文件部署到服务器上后不需要重新启动JBoss(Tomcat不支这种特性)。war文件的部署很简单,直接将war文件拷贝到JBoss/server/default/deploy目录下即可。
2.JBoss的目录结构
bin:包含各种脚本文件以及相关文件,比如run.bat和shutdown.bat批处理文件。
client:存储配置信息和可能被Java客户端应用程序或外部Web容器用到的jar文件。
docs:保存在JBoss中引用到的XML文件和DTD文件(这里也提供了在JBoss中如何写配置文件的例子)。该目录下有针对不同的数据库(如MySql、Oracle、SQL Server、Postgres等)配置数据源的JCA配置文件。
lib:一些 JAR,JBoss 启动时加载,且被所有 JBoss 配置共享。(不要把你的库放在这里)
server: 这里的每一个子目录对应着一个服务器配置。该配置由运行脚本文件时的参数"-c <配置名称>"来确定。在server目录下有三个配置例子,即all、default和minimal,每一个配置安装的服务都不一样。 其中default下是缺省配置。
minimal:仅加载启动JBoss所需的最少服务,如日志服务、JNDI和URL部署扫描器(发现新的部署),不包含Web容器、EJB和JMS。
all:启动所有的服务,包括RMI/IIOP、集群服务和Web服务部署器(默认配置不会被加载)。
启动JBoss时,如果run.bat不带任何参数,则使用的配置是server/default目录下的配置。如果要以其它目录下的配置启动JBoss,可以使用如下参数:
run -c all
上述命令将以all目录下的配置信息启动JBoss。也可以在server目录下新建目录,按自己的需要写配置文件。
下面以default目录为例,介绍服务器配置的目录结构。
conf:该目录下有指定核心服务的jboss-service.xml文件,也可以放其它服务配置的文件。
data:该目录是JBoss内置的数据库Hypersonic存储数据的地方,也是JBossMQ(the JBoss implementation of JMS)存储相关信息的地方。
deploy: 这是部署J2EE应用程序(jar、war和ear文件)的位置,只需将相应文件拷贝到该目录下即可。该目录也用来热部署服务和JCA资源适配器。已经有 一些服务部署到这个目录了,如jmx-console,你启动JBoss后即可访问。JBoss会周期性的扫描deploy目录,当有任何组件改 变,JBoss会重新部署该程序。
lib:存放服务器配置所需的jar文件,比如,你可以将JDBC驱动程序放在该目录下。
log:存放日志信息。JBoss使用Jakarta log4j包存储日志,在程序中你也可以直接使用该信息。
tmp:存储在部署过程中解压时产生的临时文件。
work:Tomcat编译JSP文件时的工作目录。
目录data、log、tmp和work在JBoss安装后并不存在,当JBoss运行时自动建立。
另外,连接数据库所用到的JDBC驱动程序要拷贝到JBoss_HOME /server /default /lib 目录下。
3. JBoss中的部署
JBoss中的部署过程非常的简单、直接并且支持热部署。在每一个配置中,JBoss不断的扫描一个特殊的目录的变化:$JBOSS_HOME/server/config-name/deploy。
你可以把下列文件拷贝到此目录下:
* 任何jar库(其中的类将被自动添加到JBoss的classpath中)
* EJB JAR
* WAR (Web Appliction aRrchive) 注意默认情况下context为war名称.
* EAR (Enterprise Application aRchive)
* 包含JBoss MBean定义的XML文件
* 一个包含EJB JAR、WAR或者EAR的解压缩内容,并以.jar、.war或者.ear结尾的目录
二、实体 Bean发布前的准备工作
1、配置数据源XML并放置在[jboss安装目录]/server/default/deploy目录,
把数据库驱动Jar包放置在[Jboss安装目录]\server\default\lib 目录下,
放置后需要重启Jboss服务器。如果数据源已经存在就不需要配置。
2、配置 persistence.xml文件,在文件中指定使用的源据源及各项参数。
3、把实体类和 persistence.xml文件打成 Jar,persistence.xml放在 jar文件的 META-INF目录
各种数据库的数据源配置模版你可以在[Jboss安装目录]\docs\examples\jca目录中找到,默认名称为:数据库名+ -ds.xml 。
三、日志文件设置
若需要修改JBoss默认的log4j设置,可修改JBoss安装目录"server\default\conf下的jboss-log4j.xml文件,在该文件中可以看到,log4j的日志输出在JBoss安装目录server\default\log下的server.log文件中。
不同应用生成到不同日志文件:
- <!-- 应用日志输出 -->
- <appender name="LIGHTESB" class="org.jboss.logging.appender.DailyRollingFileAppender">
- <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
- <param name="File" value="${jboss.server.log.dir}/lightesb.log"/> <!-- 就改了生成文件名称 -->
- <param name="Append" value="true"/>
- <param name="DatePattern" value="'.'yyyy-MM-dd"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
- </layout>
- </appender>
- <appender name="WS" class="org.jboss.logging.appender.DailyRollingFileAppender">
- <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
- <param name="File" value="${jboss.server.log.dir}/webservice.log"/>
- <param name="Append" value="true"/>
- <param name="DatePattern" value="'.'yyyy-MM-dd"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
- </layout>
- </appender>
- <!-- 应用日志输出 -->
- <category name="com.soa.lightesb">
- <priority value="DEBUG"/>
- <appender-ref ref="LIGHTESB"/>
- </category>
- <!--服务日志输出 -->
- <category name="com.soa.ws">
- <priority value="DEBUG"/>
- <appender-ref ref="WS"/>
- </category>
修改jboss日志级别:
由于JBOSS日志文件占用的空间太大,需要修改日志文件记录信息的级别
JBOSS服务中的记录日志文件:jboss-log4j.xml,修改<param name="Threshold" value="ERROR"/>
具体的value值有:DEBUG,INFO,WARN,ERROR.
JBOSS启动时加载顺序:
总结:
$JBOSS_HOME/common/lib =》 deployer目录下应用或者服务(包括配置的全局过滤器) =》 deploy下的数据源、队列和应用等
JBOSS每次发布的时候都会生成一些临时文件到\server\default\tmp\deploy下面去
JBOSS的机制就是,发布的时候将\server\default\deploy下面的一些基础的应用一起发布,而这些基础应用发布在temp的临时目录下,是作为所有应用的基础包,也就是说这些包的优先级要高于每个普通应用的包的。
需要注意的是:JBOSS在加载自带的核心JAR之后,将会优先加载下面的两个目录
1、D:\jboss\server\default\lib
2、D:\jboss\server\default\tmp\deploy
其中1会在2之前加载,而目录2是发布某个WAR,EAR,EJB等应用之后生成的临时的jar,这些应用的所有JAR会生成诸如temp*.jar的形式。本文开头提到的错误也就是在目录1中存在一个spring.jar的包,优先于各个应用的spring.jar包。
Jboss 5启动后只能从本机访问,不能从远程访问的解决办法
用netstat –na 查看,发现绑定到127.0.0.1上:
tcp 0 0 127.0.0.1:8080
D:\jboss-5.1.0.GA\server\default\deploy\jbossweb.sar\server.xml中的:
- <Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}"
- connectionTimeout="20000" redirectPort="8443" />
将${jboss.bind.address}修改为0.0.0.0即可
JBOSS配置数据源后的访问
- package com.test;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.logging.Logger;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- import javax.naming.NamingException;
- import javax.sql.DataSource;
- public class JDBCUtil {
- private final static Logger logger = Logger.getLogger(JDBCUtil.class.getName());
- // 数据源
- private static DataSource ds;
- private static String dsName = "java:/datasources/visesbdb";
- static {
- try {
- Context ctx = new InitialContext();
- ds = (DataSource)ctx.lookup(dsName);
- } catch (NamingException e) {
- logger.warning("Can not lookup the data source which named : " + dsName);
- e.printStackTrace();
- }
- }
- /**
- * 获取数据库连接
- *
- * @return 数据库连接/null
- */
- public static Connection getConnection(){
- Connection conn = null;
- if(ds != null){
- try {
- conn = ds.getConnection();
- } catch (SQLException e) {
- logger.warning("Get Connection failed ...");
- e.printStackTrace();
- }
- }
- return conn;
- }
- /**
- * 关闭数据库连接
- *
- * @param conn
- */
- public static void closeConnection(Connection conn){
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- *
- * 通过查询sql获取结果集中第一行,第一列的值
- *
- * @param 查询sql
- * @return
- */
- public static Object QueryUniqueResult(String query){
- Object result = null;
- Connection conn = getConnection();
- if(conn != null){
- try {
- PreparedStatement ps = conn.prepareStatement(query);
- ResultSet rs = ps.executeQuery();
- if(rs.next()){
- result = rs.getObject(1);
- }
- } catch (SQLException e) {
- logger.warning("execute query has error ...");
- e.printStackTrace();
- }
- }
- closeConnection(conn);
- return result;
- }
- }
- package com.test;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- public class TestContextListener implements ServletContextListener{
- public void contextInitialized(ServletContextEvent sce) {
- int access = 1;
- try {
- access = Integer.parseInt(JDBCUtil.QueryUniqueResult("SELECT T.CONFIG_VALUE FROM SYS_CONFIG T WHERE T.CONFIG_NAME = 'SRV_PARAMETER_CHECK_ACCESS'").toString());
- } catch (Exception e) {
- }
- System.out.println(access);
- }
- public void contextDestroyed(ServletContextEvent sce) {
- // TODO Auto-generated method stub
- }
- }
配置好数据源XML后可直接访问。
jboss会自动查找server/default/deploy目录下 **-ds.xml文件.并读取其中内容.来得到相应DataSource
上例数据库XML放在:server\default\deploy\datasources\visesbdb-ds.xml:
内部JNDI名字为:
<datasources>
<local-tx-datasource>
<jndi-name>datasources/visesbdb</jndi-name>
...
过滤器
WEB工程的FIiter需配到自己的web.xml中
JAVA工程无法定义Filter
EJB工程可以定义Filter,可以作为JBOSS的全局过滤器使用。
全局过滤器配置在server\default\deployers\jbossweb.deployer\web.xml中:
- <filter>
- <filter-name>mainFilter</filter-name>
- <filter-class>com.project.filter.MainFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>mainFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- /**
- * 该过滤器是一个全局的过滤器,过滤所有经过访问J2EE服务器的请求
- */
- public class MainFilter implements Filter {
- private static final Logger logger = LoggerFactory.getLogger(MainFilter.class);
- private ControlService cs = new ControlServiceImpl();
- @Override
- public void destroy() {
- InstanceInfo.filterIsUp = false;
- }
- @Override
- public void doFilter(ServletRequest req, ServletResponse res,
- FilterChain chain) throws IOException, ServletException {
- // 提取请求相关信息
- String requestURI = ((HttpServletRequest)req).getRequestURI();
- String ip = ServletUtils.getRequestIP((HttpServletRequest)req);
- // 当前时间[yyyy-MM-dd hh:mm:ss.SSS] 请求IP[IP] 请求地址[requestURI]
- logger.debug("[" + ip + "][" + requestURI + "]");
- // 只对SOAP请求做这些特殊操作
- // 判断是否是SOAP请求
- // 判断是否是Rest请求
- if(ServletUtils.isSoapRequest((HttpServletRequest)req) || ProxyServiceUtils.isRestRequest(((HttpServletRequest)req).getRequestURI())){
- // 记录所有访问的服务
- logger.info("[" + ip + "][" + requestURI + "]");
- // 获取服务英文名称
- String serviceNameEn = ProxyServiceUtils.getServiceNameByRequestUri(requestURI);
- // 服务鉴权
- if(cs.accessAuth(serviceNameEn, ip)){
- // 生成实例ID
- String uuid = InstanceInfo.getInstanceUUID();
- // 日志开关 1 为开启,0为关闭
- if("1".equals(Config.getConfigByName("log.switch"))){
- logger.debug("log switch is on...");
- // 封装请求对象
- RequestData rd = InstanceInfo.getRequestData();
- rd.setInstanceUUID(uuid);
- // 设置当前调用时间
- rd.setDate(new Date(System.currentTimeMillis()));
- rd.setServiceNameEn(serviceNameEn);
- rd.setRequestURI(requestURI);
- rd.setIp(ip);
- // 设置测试标志
- String testFlag = ((HttpServletRequest)req).getHeader("@test_flag");
- if(testFlag != null && com.project.ws.constants.Constants.HTTPREQUEST_FOR_TEST_SERVICE.equals(testFlag.trim())){
- rd.setIsTest(com.project.soa.ws.constants.Constants.HTTPREQUEST_FOR_TEST_SERVICE);
- }
- // 输入输出做封装处理用来获取输入输出
- HttpServletRequestWrapper reqw = new HttpServletRequestWrapper((HttpServletRequest)req);
- HttpServletResponseWrapper resw = new HttpServletResponseWrapper((HttpServletResponse)res);
- chain.doFilter(reqw, resw);
- }else{
- chain.doFilter(req, res);
- }
- InstanceInfo.removeInstanceUUID();
- }else{
- res.setContentType("text/xml;charset=UTF-8");
- res.getWriter().write(SoapUtils.getAuthSoapMsg());
- }
- }else{
- chain.doFilter(req, res);
- }
- }
- @Override
- public void init(FilterConfig config) throws ServletException {
- InstanceInfo.filterIsUp = true;
- }
- }
..
jboss之启动加载过程详解的更多相关文章
- DBA_Oracle Startup / Shutdown启动和关闭过程详解(概念)
2014-08-07 Created By BaoXinjian
- C编译器、链接器、加载器详解
摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代 ...
- Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析
Tomcat启动加载过程(一)的源码解析 今天,我将分享用源码的方式讲解Tomcat启动的加载过程,关于Tomcat的架构请参阅<Tomcat源码分析二:先看看Tomcat的整体架构>一文 ...
- AngularJS进阶(三十九)基于项目实战解析ng启动加载过程
基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...
- redis启动加载过程、数据持久化
背景 公司一年的部分业务数据放在redis服务器上,但数据量比较大,单纯的string类型数据一年就将近32G,而且是经过压缩后的. 所以我在想能否通过获取string数据的时间改为保存list数据类 ...
- IOS 应用程序启动加载过程(从点击图标到界面显示)
今天帮同事解决问题的时候发现,程序BUG是由加载过程引起的.所以当局部代码没有问题,但是程序一运行却总不是我们想要结果的时候,我们应该想想是不是因为我们忽略了试图加载过程的原因.下面我们用一个例子来简 ...
- 插件化框架解读之Android 资源加载机制详解(二)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680Android提供了一种非常灵活的资源系统,可以根据不同的条件提供 ...
- Crystal框架配置参数加载机制详解?
前言 定义 配置参数定义的形式 配置参数文件定义在哪里? 配置参数加载的优先级 如何使用配置参数? 最佳实践 Jar项目中如何定义配置参数? War项目中如何定义或重载Jar包中的配置参数? 开发人员 ...
- Spring Boot 配置加载顺序详解
使用 Spring Boot 会涉及到各种各样的配置,如开发.测试.线上就至少 3 套配置信息了.Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发.测试.线上环境使用不同的配置. 在 ...
随机推荐
- 【CV论文阅读】Unsupervised deep embedding for clustering analysis
Unsupervised deep embedding for clustering analysis 偶然发现这篇发在ICML2016的论文,它主要的关注点在于unsupervised deep e ...
- 【转】Linux软连接和硬链接
再次温习一下,操作的不多.虽然感觉都会!!!! 这次再次操作一遍!! 通过上面的测试发现,删除f1之后,软连接f3就无效了,硬链接f3则不受影响. ls -F可以看到文件的类型. 连接文件的作用? - ...
- Kafka跨集群同步工具——MirrorMaker
MirrorMaker是为解决Kafka跨集群同步.创建镜像集群而存在的.下图展示了其工作原理.该工具消费源集群消息然后将数据又一次推送到目标集群. watermark/2/text/aHR0cDov ...
- Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP
E. Product Sum Blake is the boss of Kris, however, this doesn't spoil their friendship. They often ...
- ramfs、rootfs和initramfs【转】
ramfs, rootfs and initramfs October 17, 2005 Rob Landley <rob@landley.net> =================== ...
- HTML DOM Table 对象
Table 对象 Table 对象代表一个 HTML 表格. 在 HTML 文档中 <table> 标签每出现一次,一个 Table 对象就会被创建. Table 对象集合 集合 描述 c ...
- 第五课 Struts的控制器【续】Action类的execute()方法
1.Action类的execute()方法: public ActionForward execute(ActionMapping mapping, ...
- POJ2686 Traveling by Stagecoach 状态压缩DP
POJ2686 比较简单的 状态压缩DP 注意DP方程转移时,新的状态必然数值上小于当前状态,故最外层循环为状态从大到小即可. #include <cstdio> #include < ...
- 51Nod 1450 闯关游戏 —— 期望DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1450 期望DP: INF 表示这种情况不行,转移时把不行的概率也转 ...
- Excel设定编辑列权限的方法
工具---保护--允许用户编辑区域 --新建-- 选择(或输入)引用单元格 ,区域密码:对不同的人不同的区域用不同的密码,设置完成后,保护工作表(密码用管理员的),即可