快捷搜索:

【J2EE架构师】18、万能框架Spring(一)<BR>3.1 框架

一、媒介

接着我们继承进修Sping框架的相关教程。

二、基础观点

Spring,作为一个盛行框架它给我们在日常工程中的框架搭建供给了太多的便利了,它就像一个骨架一样,你可以在上面自己去塑出肌肤与血肉并赋于它灵魂。

从本日开始我们将要继续几天基于Spring的根基上来讲软件开拓框架,因为Spring被利用的太广泛太广泛了,是以此系列教程可以作为Spring开拓的一套根基教程也可以称其为“典范或者公式化教程”吧.

此套教程会覆盖以下内容:

1) Spring+Struts1+jdbctemplate;

2) Spring+Struts1+Hibernate;

3) Spring+Struts2+ibatis;

4) Spring+Struts1、2+随意率性DAO层的Unit Test;

5)以致还会讲到若何应用Spring来构建利用法度榜样,对,你没听错应用Spring可以构建零丁运行的java应

用法度榜样,尤其在银行、保险业中有一种叫“批处置惩罚”的营业,便是利用法度榜样,那么我们应用Spring会为

我们的批处置惩罚功课带来什么样的好处呢?敬请等候!

三、Spring+Struts+jdbctemplate

3.1 框架先容

作为架构师,同时你也必须为“框架师”,架构是从广意上来讲的,它的常识必要覆盖到硬件、软件、协议以致营业背景。

然则一个架构师在项目中时它又必须是一个“框架师”,就和造屋子一样,框架搭的好,屋子造出来才能稳固。

我们就先来看我们第一幢屋子的脚手加架-Spring在我们项目中的应用吧,先来看架构图,一样平常我爱好用Visio来画架构图,画完后直接在Visio的workspace里ctrl+a全选后回到 word后按ctrl+v,这样你的word文本中就有了一幅visio的图了,而你在word文档中双击这个visio图它会自动在当前的文档中打开visio的workspace以便于你来编辑你的visio图,这样你就不用往返在word与 visio间进行切换了,也不用每次把visio转成jpg后再到word中插入图片了,这是一个标准操作模式,盼望能够为大年夜家往后的操作带来方便。当然,日常平凡看到好的文档,好的架构图把它收藏起来、分门别类信托你的文档会越写越漂亮.

Look,这便是我们的框架。

Ø Spring

在此我们应用3.1,它认真IOC,AOP等事情,用于代理营业层(Service层)的事务。

Ø Struts

在此我们应用1.3,它认真节制层以及相关的JSP页面(采纳Struts标签)。

节制层经由过程营业层再造访数据库层。

Ø Spring Jdbc Template

认真ORMapping,因为我们应用的数据还必要进行一些繁杂的汇总与谋略,是以在未来系统开拓中还必要开拓一系列的StoreProcedure(存储历程),用jdbc template不仅可以方便机动的应用SQL查询语句,同时也为造访各类数据库的存储历程带来了方便。

该框架优点:

Ø 分层清晰,调换机动,易于扩展

上述框架采纳View Layer,Controller Layer,Service Layer,DAOLayer进行分层。层与层之间整个基于接口。

1) 逻辑的任何更改不影响到代码的运行

2) 自动代理数据库的事务操作,尤于采纳了Spring的DataSourceTransactionManager,该类是

一个完全基于AOP的事务自动代理,因为应用的是AOP中的环抱机制,是以该类会自动使用AOP功能

在数据库操作时进行事务的开启、提交、关闭并且在碰见Exception时会自动回滚。该类应用通配符

的要领,对付营业层进行事务治理。因为Controller层不直接操作DAO,而是经由过程Service层来操作

事务的,是以事务的切片定位在Service层。别的,因为一个Service措施有可能涉及到多个DAO操

作,以是将事务定位在Service层有助于维持数据的同等性。

3) 层中相关技巧的调换不影响到其它层面,层与层之间的整个基于接口,是以各个层内自身的逻辑

或者是采纳的相关技巧的变更不影响到其它层。举例来说:现在的DAO层是Spring JdbcTemplate,

假如将来换成Hibernate或者是EJB的JPA来做DAO层的话,对付全部DAO层只必要按照原有接口重

写相关的impl类,而view层, controller层与Service层的更改为“零代码”篡改。

Ø 简化设置设置设备摆设摆设,前进临盆力

本框架应用的是Spring3.0+Struts2.x作为系统框架的核心。传统的框架伴跟着一堆xml文件的设置设置设备摆设摆设,比如说用于描述Struts中Action的设置设置设备摆设摆设,层与层之间的依附关系,以致特定的class必要用到的外部变量都必要进行基于xml款式的设置设置设备摆设摆设文件的改动。

Xml设置设置设备摆设摆设文件的篡改,假如呈现一处差错每每会影响全部系统的运行,或者以致导致系统运行崩溃。而本框架应用了JDK1.6中的“全评释”技巧,除了必要篡改一个cbbs.properties文件,各层之间的调用整个应用的Annotation,比如说我们必要在一个Struts的Action中调用一个Service, 只必要在相关的Action的Class里进行如下的注释即可:

@Resource

EmailActivationService activateService;

而传统的必要作下面这样的设置设置设备摆设摆设:

设想,要是有100个类,上百个Service,再加上数百个DAO,我们的xml的设置设置设备摆设摆设将是多么的宏大年夜啊,这便是范例的“xml泛滥”,这同时也将导致程员工事情效率,临盆效率的低下。

而现在采纳了Annotation要领来搭建框架,这在极大年夜程度上使得法度榜样员与框架之间是“透明”的,让法度榜样员将更多光阴花在“营业”的实现上。这统统都用的是Spring的“评释”特点,即

“”。

Ø 该框架不必要应用容器的jdbcjndi,而自带了一个 c3p0的jdbcconnection pool,它将会跟着容器的启动而启动,停止而销亡.

Ø 实现了基础的资本保护

我们在该框架中应用了以下几种技巧的混杂来实现外部资本文件的安然保护

1)基于Spring的Properties的注入

2)在properties文件与spring的设置设置设备摆设摆设xml文件里实现了placeholder,即调换符,记着它的英文的表达叫“place holder”。

3)应用了第三方开源免费包jasypt与spring结合自动对properties文件中的关键内容如:password进行加密与解密

3.2 框架搭建

首先应用eclipse建立一个”dynamice web project”,我们管它叫”alpha”吧,我们的第一个孩子。

然后与src同级的地方建立一个resource目录,并把它加入classpath

别忘了把Defaultoutput folder:从bin改成alpha/WebContent/WEB-INF/classes

再建立一个目录叫ext-lib的目录,把tomcat的lib目录内的jsp-api.jar与servlet-api.jar两个文件拷入该文件夹内.由于我们在涉及到一些servlet与jsp的编写时,必要应用这两个jar进行编译,但我们又不能把这两个jar文件与我们的工程一路宣布到tomcat的webapp目录下,由于tomcat已经含有这两个jar文件了,以是这两个jar文件必要以下面的要领引入我们的工程而不跟着我们的工程一路宣布:

这是工程目录布局收拾完后的样子,请照着该布局在resource目录下自行建立其它几个目录(不要去管文件,先把目录建完)。

然后我们把

1)struts

2)spring

3)c3p0-0.9.1.2.jar等

一些必要的jar文件一个个都copy到我们工程的WEB-INF/lib目录下并刷新工程。这些jar在你下载的spring、struts、hibernate包中都有带,可以自行去查找.

改动我们的web.xml文件,尤其留意下面血色与加粗的部分,一粗就爽了是吧,嘿!

web.xml

xmlversion="1.0"encoding="UTF-8"?>

web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp_ID"version="2.5">

display-name>alphadisplay-name>

welcome-file-list>

welcome-file>index.jspwelcome-file>

welcome-file-list>

listener>

listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>

listener>

context-param>

param-name>contextConfigLocationparam-name>

/WEB-INF/classes/spring/**/*.xml

context-param>

filter>

filter-name>characterEncodingfilter-name>

filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>

init-param>

param-name>encodingparam-name>

param-value>UTF-8param-value>

init-param>

init-param>

param-name>forceEncodingparam-name>

param-value>trueparam-value>

init-param>

filter>

filter-mapping>

filter-name>characterEncodingfilter-name>

url-pattern>/*url-pattern>

filter-mapping>

servlet>

servlet-name>actionservlet-name>

servlet-class>org.apache.struts.action.ActionServletservlet-class>

config

/WEB-INF/struts-config.xml,

/WEB-INF/struts-config/login.xml,

/WEB-INF/struts-config/index.xml

init-param>

param-name>debugparam-name>

param-value>3param-value>

init-param>

init-param>

param-name>detailparam-name>

param-value>3param-value>

init-param>

load-on-startup>2load-on-startup>

servlet>

servlet-mapping>

servlet-name>actionservlet-name>

url-pattern>*.dourl-pattern>

servlet-mapping>

jsp-config>

taglib>

taglib-uri>/WEB-INF/struts-bean.tldtaglib-uri>

taglib-location>/WEB-INF/struts-bean.tldtaglib-location>

taglib>

taglib>

taglib-uri>/WEB-INF/struts-html.tldtaglib-uri>

taglib-location>/WEB-INF/struts-html.tldtaglib-location>

taglib>

taglib>

taglib-uri>/WEB-INF/struts-logic.tldtaglib-uri>

taglib-location>/WEB-INF/struts-logic.tldtaglib-location>

taglib>

jsp-config>

web-app>

在该web.xml文件内我们

首先:

声清楚明了把我们的工程目录下的“/WEB-INF/classes/spring/**/*.xml”让spring去加载,由于我们这些.xml文件都在我们的resource目录下,而我们的resource目录和src目录一样是会在编译时自动跑到WEB-INF/classes目录下的,是不是?

其次:

我们声清楚明了一个filter叫“characterEncoding”,该filter的感化可以支持你的工程中无论是从jsp到.do照样从.do到jsp时对付中翰墨符的输入不用你再去手动的转newString(“xxx”,”UTF-8”)这样的转码操作了。

着末:

我们声清楚明了我们的struts的action mapping文件所在的位置,我们在此处声清楚明了3个struts-config文件,主config文件为:/WEB-INF/struts-config.xml,其它两个为我们的“模拟级config文件”。

/WEB-INF/struts-config.xml

value="org.springframework.web.struts.DelegatingRequestProcessor" />

该文件中:

value="org.springframework.web.struts.DelegatingRequestProcessor" />

的感化便是把我们的struts中的action委托给了spring去治理,由于我们的统统都是经由过程action/.do入手的,是以一旦我们的action被spring托管起来后,那么action下调用的service, service调用的dao都被我们的spring进行托管了,于是统统就都可以“注入”了.

下面,我们来看我们的applicationContext.xml文件,这个异常核心的一个文件。

applicationContext.xml文件

p:algorithm="PBEWITHMD5ANDDES" p:passwordEnvName="APP_ENCRYPTION_PASSWORD" />

p:config-ref="environmentVariablesConfiguration" />

classpath:jdbc.properties

p:encryptor-ref="configurationEncryptor" p:systemPropertiesModeName="SYSTEM_PROPERTIES_MODE_OVERRIDE">

factory-method="getConfiguration" />

主要照样血色加粗的部分,解释如下:

1)

可以在你的struts的action文件中启用@Controller这样的评释将struts的action委托给spring进行治理

2)

在该“package”下所有的类都委托给了spring进行治理

3)

Ø bean id="environmentVariablesConfiguration"

Ø bean id="configurationEncryptor"

Ø Bean id="propertyConfigurer"

Ø context:property-placeholderlocation="classpath:jdbc.properties"

Ø beanid="commonsConfigurationFactoryBean"、beanid="propertiesConfiguration"

这些个bean的申明可以让你如以了局景般的去应用,请看:

我有一个jdbc.properties文件,内容如下:

jdbc.driverClassName=oracle.jdbc.OracleDriver

jdbc.databaseURL=jdbc:oracle:thin:@localhost:1521:ymkorcl

jdbc.username=alpha

jdbc.password=ENC(W1BJSjx6+1O1z3ArmojmaQG+r80ty3zX)

留意这个jdbc.password,这个value是被加密了的。

然后我有一个datasource.xml文件,内容如下:

${jdbc.driverClassName}"/>

="${jdbc.databaseURL}" />

${jdbc.username}" />

="${jdbc.password}" />

看到了没有?这就叫“property-placeholder“,由于。。。由于假如哪天我的数据库换成了mysql后,是不是我只要在我的jdbc.properties文件里换换内容就可以了而不必要再去动这个datasource.xml文件啊?

那么说到加密这个问题很简单,这个加密我们用的是“StandardPBEStringEncryptor”里的

PBEWITHMD5ANDDES p:passwordEnvName="APP_ENCRYPTION_PASSWORD",所谓PBE便是password base的意思,是以我们这个加密首先用的是DES,然后为懂得密这个DES还必要一个password,而这个password我们设在哪边?

environmentVariablesConfiguration" /

啊。。。environmentVariablesConfiguration, 以是我们来看:

看到了没有,假如你是linux系统则必要在/etc/profile文件中加入:

export APP_ENCRYPTION_PASSWORD=”aaaaaa”

以是我们为懂得这个DES密码时必要一个口令,这个口令在我们的系统情况变量,值为六个a。

我们看到在commonsConfigurationFactoryBean里我们自定义了一个class为:

org.sky.ssh1.alpha.util.CommonsConfigurationFactoryBean的类,我们来看这个类吧.

org.sky.ssh1.alpha.util.CommonsConfigurationFactoryBean内容:

package org.sky.ssh1.alpha.util;

import static org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.DEFAULT_PLACEHOLDER_PREFIX;

import static org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.DEFAULT_PLACEHOLDER_SUFFIX;

import static org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_FALLBACK;

import static org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Properties;

import java.util.Set;

import org.apache.commons.configuration.CompositeConfiguration;

import org.apache.commons.configuration.Configuration;

import org.apache.commons.configuration.ConfigurationConverter;

import org.apache.commons.configuration.PropertiesConfiguration;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.jasypt.encryption.StringEncryptor;

import org.jasypt.properties.PropertyValueEncryptionUtils;

import org.springframework.beans.factory.BeanDefinitionStoreException;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import org.springframework.core.Constants;

import org.springframework.util.StringUtils;

/**

* Creates a commons configuration factory bean, by using the best of both

* worlds Jakarta Commons Configuration and SpringSource PropertyPlaceHolder

*

* @author lifetragedy

* @since Apr 28, 2009

*

*/

public class CommonsConfigurationFactoryBean extends

org.springmodules.commons.configuration.CommonsConfigurationFactoryBean {

protected final Log logger = LogFactory.getLog(getClass());

private CompositeConfiguration configuration;

private static final Constants constants = new Constants(

PropertyPlaceholderConfigurer.class);

private String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;

private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;

private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;

private boolean searchSystemEnvironment = true;

private boolean ignoreUnresolvablePlaceholders = false;

private StringEncryptor encryptor;

@SuppressWarnings("unused")

private String nullValue = null;

public CommonsConfigurationFactoryBean() {

super();

}

public CommonsConfigurationFactoryBean(Configuration configuration) {

super(configuration);

}

@Override

public Object getObject() throws Exception {

return (configuration != null) ? ConfigurationConverter

.getProperties(configuration) : null;

}

@Override

public void afterPropertiesSet() throws Exception {

super.afterPropertiesSet();

processConfiguration((Properties) super.getObject());

}

@Override

public CompositeConfiguration getConfiguration() {

return configuration;

}

protected void processConfiguration(final Properties properties) {

Configuration propertiesConfiguration = new PropertiesConfiguration();

if (properties != null) {

for (Iterator iter = properties.entrySet().iterator(); iter

.hasNext();) {

Map.Entry entry = (Map.Entry) iter.next();

String key = (String) entry.getKey();

String value = parseStringValue((String) entry.getValue(),

properties, new HashSet());

if (value != null && value.trim().length() > 0)

// logger.info("the key======"+key+"value======"+value);

propertiesConfiguration.setProperty(key, value);

}

}

configuration = new CompositeConfiguration(propertiesConfiguration);

}

// Source taken SpringSource class PropertyPlaceholderConfigurer for the

// placeholder logic

/**

* Set the prefix that a placeholder string starts with. The default is

* "${".

*

* @see #DEFAULT_PLACEHOLDER_PREFIX

*/

public void setPlaceholderPrefix(String placeholderPrefix) {

this.placeholderPrefix = placeholderPrefix;

}

/**

* Set the suffix that a placeholder string ends with. The default is "}".

*

* @see #DEFAULT_PLACEHOLDER_SUFFIX

*/

public void setPlaceholderSuffix(String placeholderSuffix) {

this.placeholderSuffix = placeholderSuffix;

}

/**

* Set the system property mode by the name of the corresponding constant,

* e.g. "SYSTEM_PROPERTIES_MODE_OVERRIDE".

*

* @param constantName

*name of the constant

* @throws java.lang.IllegalArgumentException

*if an invalid constant was specified

* @see #setSystemPropertiesMode

*/

public void setSystemPropertiesModeName(String constantName)

throws IllegalArgumentException {

this.systemPropertiesMode = constants.asNumber(constantName).intValue();

}

/**

* Set how to check system properties: as fallback, as override, or never.

* For example, will resolve ${user.dir} to the "user.dir" system property.

*

* The default is "fallback": If not being able to resolve a placeholder

* with the specified properties, a system property will be tried.

* "override" will check for a system property first, before trying the

* specified properties. "never" will not check system properties at all.

*

* @see #SYSTEM_PROPERTIES_MODE_NEVER

* @see #SYSTEM_PROPERTIES_MODE_FALLBACK

* @see #SYSTEM_PROPERTIES_MODE_OVERRIDE

* @see #setSystemPropertiesModeName

*/

public void setSystemPropertiesMode(int systemPropertiesMode) {

this.systemPropertiesMode = systemPropertiesMode;

}

/**

* Set whether to search for a matching system environment variable if no

* matching system property has been found. Only applied when

* "systemPropertyMode" is active (i.e. "fallback" or "override"), right

* after checking JVM system properties.

*

* Default is "true". Switch this setting off to never resolve placeholders

* against system environment variables. Note that it is generally

* recommended to pass external values in as JVM system properties: This can

* easily be achieved in a startup script, even for existing environment

* variables.

*

* NOTE: Access to environment variables does not work on the Sun VM

* 1.4, where the corresponding {@link System#getenv} support was disabled -

* before it eventually got re-enabled for the Sun VM 1.5. Please upgrade to

* 1.5 (or higher) if you intend to rely on the environment variable

* support.

*

* @see #setSystemPropertiesMode

* @see java.lang.System#getProperty(String)

* @see java.lang.System#getenv(String)

*/

public void setSearchSystemEnvironment(boolean searchSystemEnvironment) {

this.searchSystemEnvironment = searchSystemEnvironment;

}

/**

* Set whether to ignore unresolvable placeholders. Default is "false": An

* exception will be thrown if a placeholder cannot be resolved.

*/

public void setIgnoreUnresolvablePlaceholders(

boolean ignoreUnresolvablePlaceholders) {

this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;

}

/**

* Set a value that should be treated as null when resolved as

* a placeholder value: e.g. "" (empty String) or "null".

*

* Note that this will only apply to full property values, not to parts of

* concatenated values.

*

* By default, no such null value is defined. This means that there is no

* way to express null as a property value unless you explictly

* map a corresponding value here.

*/

public void setNullValue(String nullValue) {

this.nullValue = nullValue;

}

/**

* Set the Text based Encryptor which will be used to decrypt the passwords

* as per JASYPT

*

* @param encryptor

*/

public void setEncryptor(StringEncryptor encryptor) {

this.encryptor = encryptor;

}

/**

* Parse the given String value recursively, to be able to resolve nested

* placeholders (when resolved property values in turn contain placeholders

* again).

*

* @param strVal

*the String value to parse

* @param props

*the Properties to resolve placeholders against

* @param visitedPlaceholders

*the placeholders that have already been visited during the

*current resolution attempt (used to detect circular references

*between placeholders). Only non-null if we're parsing a nested

*placeholder.

* @throws BeanDefinitionStoreException

*if invalid values are encountered

* @see #resolvePlaceholder(String, java.util.Properties, int)

*/

@SuppressWarnings("unchecked")

protected String parseStringValue(String strVal, Properties props,

Set visitedPlaceholders) throws BeanDefinitionStoreException {

StringBuffer buf = new StringBuffer(strVal);

int startIndex = strVal.indexOf(this.placeholderPrefix);

while (startIndex != -1) {

int endIndex = findPlaceholderEndIndex(buf, startIndex);

if (endIndex != -1) {

String placeholder = buf.substring(startIndex

+ this.placeholderPrefix.length(), endIndex);

if (!visitedPlaceholders.add(placeholder)) {

throw new BeanDefinitionStoreException(

"Circular placeholder reference '" + placeholder

+ "' in property definitions");

}

// Recursive invocation, parsing placeholders contained in the

// placeholder key.

placeholder = parseStringValue(placeholder, props,

visitedPlaceholders);

// Now obtain the value for the fully resolved key...

String propVal = resolvePlaceholder(placeholder, props,

this.systemPropertiesMode);

if (propVal != null) {

// Recursive invocation, parsing placeholders contained in

// the

// previously resolved placeholder value.

propVal = parseStringValue(propVal, props,

visitedPlaceholders);

buf.replace(startIndex,

endIndex + this.placeholderSuffix.length(), propVal);

if (logger.isTraceEnabled()) {

logger.trace("Resolved placeholder '" + placeholder

+ "'");

}

startIndex = buf.indexOf(this.placeholderPrefix, startIndex

+ propVal.length());

} else if (this.ignoreUnresolvablePlaceholders) {

// Proceed with unprocessed value.

startIndex = buf.indexOf(this.placeholderPrefix, endIndex

+ this.placeholderSuffix.length());

} else {

throw new BeanDefinitionStoreException(

"Could not resolve placeholder '" + placeholder

+ "'");

}

visitedPlaceholders.remove(placeholder);

} else {

startIndex = -1;

}

}

return convertPropertyValue(buf.toString());

}

private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {

int index = startIndex + this.placeholderPrefix.length();

int withinNestedPlaceholder = 0;

while (index0) {

withinNestedPlaceholder--;

index = index + this.placeholderSuffix.length();

} else {

return index;

}

} else if (StringUtils.substringMatch(buf, index,

this.placeholderPrefix)) {

withinNestedPlaceholder++;

index = index + this.placeholderPrefix.length();

} else {

index++;

}

}

return -1;

}

/**

* Resolve the given placeholder using the given properties, performing a

* system properties check according to the given mode.

*

* Default implementation delegates to resolvePlaceholder

* (placeholder, props) before/after the system properties check.

*

* Subclasses can override this for custom resolution strategies, including

* customized points for the system properties check.

*

* @param placeholder

*the placeholder to resolve

* @param props

*the merged properties of this configurer

* @param systemPropertiesMode

*the system properties mode, according to the constants in this

*class

* @return the resolved value, of null if none

* @see #setSystemPropertiesMode

* @see System#getProperty

* @see #resolvePlaceholder(String, java.util.Properties)

*/

protected String resolvePlaceholder(String placeholder, Properties props,

int systemPropertiesMode) {

String propVal = null;

if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) {

propVal = resolveSystemProperty(placeholder);

}

if (propVal == null) {

propVal = resolvePlaceholder(placeholder, props);

}

if (propVal == null

&& systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) {

propVal = resolveSystemProperty(placeholder);

}

return propVal;

}

/**

* Resolve the given placeholder using the given properties. The default

* implementation simply checks for a corresponding property key.

*

* Subclasses can override this for customized placeholder-to-key mappings

* or custom resolution strategies, possibly just using the given properties

* as fallback.

*

* Note that system properties will still be checked before respectively

* after this method is invoked, according to the system properties mode.

*

* @param placeholder

*the placeholder to resolve

* @param props

*the merged properties of this configurer

* @return the resolved value, of null if none

* @see #setSystemPropertiesMode

*/

protected String resolvePlaceholder(String placeholder, Properties props) {

return convertPropertyValue(props.getProperty(placeholder));

}

/**

* Resolve the given key as JVM system property, and optionally also as

* system environment variable if no matching system property has been

* found.

*

* @param key

*the placeholder to resolve as system property key

* @return the system property value, or null if not found

* @see #setSearchSystemEnvironment

* @see java.lang.System#getProperty(String)

* @see java.lang.System#getenv(String)

*/

protected String resolveSystemProperty(String key) {

try {

String value = System.getProperty(key);

if (value == null && this.searchSystemEnvironment) {

value = System.getenv(key);

}

return value;

} catch (Throwable ex) {

if (logger.isDebugEnabled()) {

logger.debug("Could not access system property '" + key + "': "

+ ex);

}

return null;

}

}

protected String convertPropertyValue(String originalValue) {

if (!PropertyValueEncryptionUtils.isEncryptedValue(originalValue)) {

return originalValue;

}

if (this.encryptor != null) {

return PropertyValueEncryptionUtils.decrypt(originalValue,

this.encryptor);

}

return PropertyValueEncryptionUtils.decrypt(originalValue,

this.encryptor);

}

}

懂得完了applicationContext.xml文件内容后我们继承看下去:

jdbc.properties文件

jdbc.driverClassName=oracle.jdbc.OracleDriver

jdbc.databaseURL=jdbc:oracle:thin:@localhost:1521:ymkorcl

jdbc.username=alpha

jdbc.password=ENC(W1BJSjx6+1O1z3ArmojmaQG+r80ty3zX)

若何把这个jdbc.password后的值进行加密呢?我们来看:

Jasypt加密解密步骤一

首先你要下载最新版的jasypt,今朝是1.9,除了把这三个jar文件

Jasypt加密解密步骤二

打开一个command窗口输入如下的敕令,假设我们的jdbc.password后的值为:password_1,要把这个password_1用PBEWITHMD5ANDDES加密,我们输入如下的敕令:

把OUTPUT这段复制下来后放入我们的properties 文件内,并用ENC()包括起来,这样我们的spring就会在我们的J2EE容器启动时碰着指定的properties文件中假如含有ENC()括起来的器械,去自动履行相称于如下的解密敕令了:

而这边的password便是你在情况变量中设定的:APP_ENCRYPTION_PASSWORD的值。

datasource.xml文件

aop:pointcut id="serviceMethod" expression="execution(* org.sky.ssh1.alpha.service.impl.*.*(..))"/>

您可能还会对下面的文章感兴趣: