??xml version="1.0" encoding="utf-8" standalone="yes"?><!-- 列表lg导出qo?nbsp;-->
<filter>
<filter-name>eXtremeExport</filter-name>
<filter-class>
org.extremecomponents.table.filter.ExportFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>eXtremeExport</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<!-- 著名 Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
看不出有什么问?可当我插入测试数据时全是q.
数据库本w是没有问题?
后来l于扑ֈ了解决的Ҏ,原创列表lg的filter?br />
CharacterEncodingFilter的过滤有影响.调整一下顺序就行了.
<!-- 著名 Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 列表lg导出qo?nbsp;-->
<filter>
<filter-name>eXtremeExport</filter-name>
<filter-class>
org.extremecomponents.table.filter.ExportFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>eXtremeExport</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
调整后CharacterEncodingFilter表现良好,一切正?׃会再出来
q的问题了.
]]>
如没有可到我的网盘下?
bean.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- mail提供?nbsp;-->
<property name="host">
<value>smtp.163.com</value>
</property>
<property name="javaMailProperties">
<props>
<!-- 用户认证 -->
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.timeout">25000</prop>
</props>
</property>
<!-- 用户?nbsp;-->
<property name="username">
<value>78688287</value>
</property>
<!-- 密码 -->
<property name="password">
<value>******</value>
</property>
</bean>
</beans>
MailTest.java:
package com;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class MailTest
{
public static void main(String[] args)
{
//得到spring的context对象
ApplicationContext ctx = new FileSystemXmlApplicationContext("/src/com/bean.xml");
//mail提供?/span>
MailSender sender = (MailSender) ctx.getBean("mailSender");
//创徏一个简单mail消息对象
SimpleMailMessage smm = new SimpleMailMessage();
//收g?/span>
smm.setTo("zdw@live.cn");
//发g人地址
smm.setFrom("78688287@163.com");
//标题
smm.setSubject("test");
//内容
smm.setText("q是关于Spring Mail抽象层的单测?/span>");
//发?/span>
sender.send(smm);
//提示信息
System.out.println("Send Ok!!");
}
}
]]>package com;
public class MyClass
{
public void foo(int age, String name)
{
System.out.println("Inside foo(int,String)");
}
public static void main(String[] args)
{
MyClass myClass = new MyClass();
myClass.foo(1, "zdw");
}
}
package com;
public aspect HelloWorld
{
//切入?/span>
pointcut callPointcut() : call(void MyClass.foo(int,String));
//前置通知
before() : callPointcut()
{
System.out.println("Hello World");
System.out.println("In the advice attached to the call pointcut");
}
}
]]>
]]>
Z理解AOP如何做到q点Q考虑一下记日志的工作。日志本w不太可能是你开发的ȝ序的主要d。如果能?#8220;不可见的”、通用的日志代码注入主E序中,那该多好啊。AOP可以帮助你做到?
Spring framework是很有前途的AOP技术。作ZU非늕性的Q轻型的AOP frameworkQ你无需使用预编译器或其他的元标{,便可以在JavaE序中用它。这意味着开发团队里只需一对付AOP frameworkQ其他hq是象往怸LE?
AOP是很多直觉难以理解的术语的根源。幸q的是,你只要理解三个概念,可以编写AOP模块。这三个概念是:adviceQpointcut?advisor。advice是你惛_别的E序内部不同的地Ҏ入的代码。pointcut定义了需要注入advice的位|,通常是某个特定的cȝ一?publicҎ。advisor是pointcut和advice的装配器Q是advice注入ȝ序中预定义位|的代码?
既然我们知道了需要用advisor向主要代码中注入“不可见的”adviceQ让我们实现一个Spring AOP的例子。在q个例子中,我们实C个before adviceQ这意味着advice的代码在被调用的publicҎ开始前被执行。以下是q个before advice的实C码:
package com.company.springaop.test;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class TestBeforeAdvice implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target)
throws Throwable {
System.out.println("Hello world! (by "
+ this.getClass().getName()
+ ")");
}
}
接口MethodBeforeAdvice只有一个方法before需要实玎ͼ它定义了advice的实现。beforeҎq三个参数Q它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名U可以用作判断是否执行代码的条g。Object[] args是传l被调用的publicҎ的参数数l。当需要记日志Ӟ参数args和被执行Ҏ的名Uͼ都是非常有用的信息。你也可以改变传lm的参敎ͼ但要心使用q个功能Q编写最初主E序的程序员q不知道ȝ序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用?
在下面的BeanImplcMQ每个publicҎ调用前,都会执行adviceQ?
package com.company.springaop.test;
public class BeanImpl implements Bean {
public void theMethod() {
System.out.println(this.getClass().getName()
+ "." + new Exception().getStackTrace()[0].getMethodName()
+ "()"
+ " says HELLO!");
}
}
cBeanImpl实现了下面的接口BeanQ?
package com.company.springaop.test;
public interface Bean {
public void theMethod();
}
虽然不是必须使用接口Q但面向接口而不是面向实现编E是良好的编E实践,Spring也鼓p样做?
pointcut和advice通过配置文g来实玎ͼ因此Q接下来你只需~写L法的Java代码Q?
package com.company.springaop.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
//Read the configuration file
ApplicationContext ctx
= new FileSystemXmlApplicationContext("springconfig.xml");
//Instantiate an object
Bean x = (Bean) ctx.getBean("bean");
//Execute the public method of the bean (the test)
x.theMethod();
}
}
我们从读入和处理配置文g开始,接下来马上要创徏它。这个配|文件将作ؓ_合E序不同部分?#8220;胶水”。读入和处理配置文g后,我们会得C个创建工厂ctx。Q何一个Spring理的对象都必须通过q个工厂来创建。对象通过工厂创徏后便可正怋用?
仅仅用配|文件便可把E序的每一部分l装h?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--CONFIG-->
<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.company.springaop.test.Bean</value>
</property>
<property name="target">
<ref local="beanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>theAdvisor</value>
</list>
</property>
</bean>
<!--CLASS-->
<bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>
<!--ADVISOR-->
<!--Note: An advisor assembles pointcut and advice-->
<bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theBeforeAdvice"/>
</property>
<property name="pattern">
<value>com\.company\.springaop\.test\.Bean\.theMethod</value>
</property>
</bean>
<!--ADVICE-->
<bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/>
</beans>
四个bean定义的次序ƈ不重要。我们现在有了一个adviceQ一个包含了正则表达式pointcut的advisorQ一个主E序cd一个配|好的接口,通过工厂ctxQ这个接口返回自己本w实现的一个引用?
BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创徏一个bean元素Qƈ指定了一个实现类。这是全部的工作?
advisor通过Spring framework提供的一个RegexMethodPointcutAdvisorcL实现。我们用advisor的一个属性来指定它所需?advice-bean。第二个属性则用正则表辑ּ定义了pointcutQ确保良好的性能和易L?
最后配|的是beanQ它可以通过一个工厂来创徏。bean的定义看h比实际上要复杂。bean是ProxyFactoryBean的一个实玎ͼ它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义Q?
Spring工具
虽然你可以手工修改Ant构徏脚本Q但使用SpringUIQ译注:SpringUI现在是Spring framework的一部分Qƈ改名为spring-ideQ,使用Spring AOP变得很简单,只要点点鼠标卛_。你可以把SpringUI安装成Eclipse的一个plug-in。然后,你只需在你的project上右击鼠标,q择“add Spring Project Nature”。在project属性中Q你可以?#8220;Spring Project”下添加Spring配置文g。在~译前把下面的类库加入projectQaopalliance.jarQcommons- logging.jarQjakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息:
(logging information)
Hello world! (by com.company.springaop.test.TestBeforeAdvice)
com.company.springaop.test.BeanImpl.theMethod() says HELLO!
优点和缺?/span>
Spring比v其他的framework更有优势Q因为除了AOP以外Q它提供了更多别的功能。作Z个轻型frameworkQ它在J2EE 不同的部分都可以发挥作用。因此,即不想使用Spring AOPQ你可能q是想用Spring。另一个优ҎQSpringq不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一开始。读了本文后Q你应该可以更好地理解Spring reference了。Spring唯一的缺Ҏ~Z更多的文,但它的mailing list是个很好的补充,而且会不断地出现更多的文?/span>
]]>
在J2EE的整个发展历E中Q现在正是一个非常时刅R从很多斚w来说QJ2EE都是一个伟大的成功Q它成功地在从前没有标准的地方徏立了标准Q大大提升了企业UY件的开攄度,q且得到了整个行业和开发者的q泛认可。然而,J2EE在一些方面已l开始捉襟见肘。J2EE应用开发的成本通常很高。J2EE应用目臛_和从前的非J2EE目一样容易失败——如果不是更Ҏp|的话。这Lp|率高得让人难以接受。在q样的失败率之下QY件开发几乎变成了运气。而在J2EE遭遇p|的场景中QEJB通常都扮演着重要的角艌Ӏ因此,J2EEC不断地向着更简单的解决Ҏ、更用EJB的方向发?sup>[1]。然而,每个应用E序都需要一些基设施Q拒l用EJBq不意味着拒绝EJB所采用的基设施解决Ҏ。那么,如何利用现有的框架来提供q些基础设施服务呢,伴随着q个问题的提出,一个轻量的J2EE解决Ҏ出现了,q就是Spring Framework?br />
Spring是ؓ化企业pȝ开发而诞生的QSpring框架为J2EE应用常见的问题提供了单、有效的解决ҎQ用SpringQ你可以用简单的POJO(Plain Old Java Object)来实现那些以前只有EJB才能实现的功能。这样不只是能简化服务器端开发,MJavapȝ开发都能从Spring的简单、可试和松耦合特征中受益。可以简单的_Spring是一个轻量的反向控ӞIoCQ和面向切面~程QAOPQ容器框?sup>[3]。Spring IoCQ借助于依赖注入设计模式,使得开发者不用理会对象自w的生命周期及其关系Q而且能够改善开发者对J2EE模式的用;Spring AOPQ借助于Spring实现的拦截器Q开发者能够实C声明的方式用企业服务Q比如安全性服务、事务服务等。Spring IoC?Spring ; AOPl合Q一起Ş成了SpringQ这样一个有机整体,使得构徏轻量U的J2EE架构成ؓ可能Q而且事实证明Q非常有效。没有Spring IoC的Spring AOP是不完善的,没有Spring AOP的Spring IoC是不健壮的。本文是以Spring架构的成功的实际商务pȝ目景,阐述了反向控制原理和面向切面的编E技术在Spring框架中的应用Q同时抽取适量代码C意具体应用Qƈ和传l开发模式进行对比,展示了Spring framework的简单,高效Q可l护{优炏V?br />
1、Spring IoC 1.1 反向控制原理
反向控制是Spring框架的核心。但是,反向控制是什么意思?到底控制的什么方面被反向了呢Q?004q美国专家Martin Fowler发表了一论文《Inversion of Control Containers and the Dependency Injection pattern》阐qCq个问题Q他ȝ说是获得依赖对象的方式反向了Q根据这个启C,他还为反向控制提Z一个更贴切的名字:Dependency Injection(DI 依赖注入)?br />
通常Q应用代码需要告知容器或框架,让它们找到自w所需要的c?然后再由应用代码创徏待用的对象实例。因此,应用代码在用实例之前,需要创建对象实例。然而,IoC模式?创徏对象实例的Q务交lIoC容器或框?实现了IoC设计模式的框架也被称为IoC容器)Q得应用代码只需要直接用实例,q就是IoC。相对IoC 而言Q?#8220;依赖注入”的确更加准确的描qCq种设计理念。所谓依赖注入,即组件之间的依赖关系由容器在q行期决定,形象的来_即由容器动态的某U依赖关pL入到lg之中?br />
1.2 IoC在Spring中的实现
M重要的系l都需要至两个相互合作的cL完成业务逻辑。通常Q每个对象都要自p责得到它的合作(依赖Q对象。你会发玎ͼq样会导致代码耦合度高而且难于试。用IoCQ对象的依赖都是在对象创建时p责协调系l中各个对象的外部实体提供的Q这样软glg松散q接成ؓ可能。下面示意了Spring IoC 应用Q步骤如下:
Q?Q定义Action接口Qƈ为其定义一个executeҎQ以完成目标逻辑。多q前QGoF在《Design PatternQElements of Reusable Object-Oriented Software》一书中提出“Programming to an InterfaceQnot an implementation”的原则,q里首先业务对象抽象成接口Q正是ؓ了实施这个原则?br />
Q?Q类UpperAction实现Action接口Q在此类中,定义一个String型的域messageQƈ提供相应的setter和getterҎQ实现的executeҎ如下Q?br />
public String execute (String str) {
return (getMessage () + str).toUpperCase () ;
}
Q?Q编写Spring配置文gQbean.xmlQ?br />
QbeansQ?br />
Qbean id="TheAction" class="net.chen.spring.qs.UpperAction"Q?br />
Qproperty name="message"Q?br />
QvalueQHeLLoQ?/span>/valueQ?br />
Q?/span>/propertyQ?br />
Q?/span>/beanQ?br />
Q?/span>/beansQ?/span>
Q?Q测试代?br />
public void testQuickStart () {
ApplicationContext ctx=new
FileSystemXmlApplicationContext ("bean.xml");
Action a= (Action) ctx.getBean ("TheAction");
System.out.println (a. execute ("Rod Johnson"));
}
上面的测试代码中Q我们根?bean.xml"创徏了一个ApplicationContext实例Qƈ从此实例中获取我们所需的Action实现Q运行测试代码,我们看到控制台输出:
……
HELLO ROD JOHNSON
仔细观察一下上面的代码Q可以看刎ͼ
Q?Q我们的lgq不需要实现框架指定的接口Q因此可以轻杄组件从Spring中脱,甚至不需要Q何修改,q在ZEJB框架实现的应用中是难以想象的?br />
Q?Q组仉的依赖关pd,极大改善了代码的可重用性。Spring的依赖注入机Ӟ可以在运行期为组仉|所需资源Q而无需在编写组件代码时加以指定,从而在相当E度上降低了lg之间的耦合?br />
Springl我们带来了如此q般的好处,那么Q反q来Q让我们试想一下,如果不用Spring框架Q回到我们传l的~码模式Q情况会是怎样呢?
首先Q我们必ȝ写一个配|文件读取类Q以实现Message属性的可配|化?br />
其次Q得有一个Factory模式的实玎ͼq结合配|文件的d完成Action的动态加载。于是,我们实现了一个ActionFactory来实现这个功能:
public class ActionFactory {
public static Action getAction (String actionName) {Properties pro = new Properties ();
try {
pro.load (new FileInputStream ("config.properties"));
String actionImplName =(String)pro.get(actionName);
String actionMessage =(String) pro.get (actionName+"_msg");
Object obj =Class.forName (actionImplName).newInstance ();
BeanUtils.setProperty(obj,"message",actionMessage);
return (Action) obj;
} catch (FileNotFoundException e) {
……
}
}
配置文g则采用properties文g形式如下所C:
TheAction=net.chen.spring.qs.UpperAction
TheAction_msg=HeLLo
试代码也作相应修改。现在不论实现的好坏QM通过上面新增的多行代码,l于实现了类似的功能。如果现在有了一个新的需求,q样q个ActionFactory每次都新Z个类的实例,昄q对pȝ性能不利Q考虑到我们的两个Action都是U程安全的,修改一下ActionFactoryQ保持系l中只有一个Action实例供其它线E调用。另外Action对象创徏后,需要做一些初始化工作。修改一下ActionFactoryQ其在创徏Action实例之后Q随卛_调用Action.initҎ执行初始化。Action的处理这样就差不多了。下面我们来看看另外一个Factory
……
往往q些pȝ开发中最常见的需求,会导致我们的代码q速膨胀Q而Spring IoC的出玎ͼ则大大缓解了q样的窘境。通过以上实例Q可以看出,Spring IoC为我们提供了如下几方面的优势Q?br />
Q?Q应用组件不需要在q行时寻扑օ协作者,因此更易于开发和~写应用Q?br />
Q?Q由于借助于IoC容器理lg的依赖关p,使得应用的单元测试和集成试更利于展开Q?br />
Q?Q通常Q在借助于IoC容器关系业务对象的前提下Q很需要用具体IoC容器提供的APIQ这使得集成现有的遗留应用成为可能?br />
因此Q通过使用IoC能够降低lg之间的耦合度,最l,能够提高cȝ重用性,利于试Q而且更利于整个品或pȝ集成和配|?br />
]]>
1.W一U,使用数组
代码
2.W二U,只用通配W?/span>
代码
//但此U方法只Ҏ件系l中的xml文g有效Q针对jar包中的无?
3.W三U,引入
代码
//在a1.xml?
执行resource路径为相对a1.xml的\?
需明确的几个概?
1、通知(Advice)Q用于告知系l将有哪些新的行为?br />
2、切入点(Pointcut):定义了通知应该在应用到那些q接?br />
3、目标对?/span>(Target)Q被通知的对象?br />
4?/span> 代理(Proxy)Q将通知应用到目标对象后创徏的对象?/span>
Spring有两U代理创建方式:
1.如果目标对象实现了一个或多个接口暴露的方法,Spring?/span>JDK?/span>java.lang.reflect.Proxy创徏代理。这个类?/span>Spring动态生一个新的类Q它实现了所需的接口,l入了通知Qƈ且代理目标的所有请求。(q篇主要介绍q个方式Q?/span>
2.如果目标对象没有实现M接口Q?span style="font-family: 'Courier New'">Spring使用CGLIB库生成目标对象的子类。在创徏q个子类的时候,Spring通知l入Qƈ且将对目标对象的调用委托l这个子cR?/span>
下面以一个实例说?span style="font-family: 'Courier New'">Spring AOP的基本开发方法:
一Q?/span>创徏通知
Springq接Ҏ型是建立在方法拦截上Q这意味着你编写的Spring通知会在Ҏ调用周围的各个地方织入系l中?/span>
?/span>1
TestAopServiceAdvice实现了接?/span>MethodBeforeAdvice(前置通知)Qƈ实现它的惟一的方?/span>beforeQ这个类可以在调用目标对象前被调用。同Lq有AfterReturningAdvice(后置通知)Q?/span>MethodInterceptor(环绕通知)Q异帔R知(ThrowsAdvice)Q引入通知{?/span>
在这个方法中我们输出了一个字W串TestAopServiceAdviceQ用于验证这个方法是否在目标对象前调用了?/span>
注意Q?/span>我们无法改变beforeҎ中的参数args?/span>target中的|args中存的是原来要传入目标对象的变量Q?/span>targetx目标对象?/span>
二.配置Spring XML配置文g
要在Spring中实?/span>AOPQ一般情况下需要配|?/span>4?/span>beanQ?/span>
1Q?/span>目标对象Q?/span>targetQ?/span>
2Q?/span>通知(advice)
3Q?/span>切入?/span>(pointcut)
4Q?/span>代理(proxy)
?/span>2
切入点又分ؓ静态切入点和动态切入点
1?/span> 静态切入点的意思是通知L被执?/span>,也是最常用的一U切入点?br />
2?/span> 动态切入点Ҏq行时方法的参数值决定通知是否被执行?/span>
在图2中,定义了用了一?/span>Spring提供的静态切入点
NameMatchMethodPointAdvisorQ它保证了当被调用的Ҏ的名字与l出的映名字相匚w的时候,q个切入Ҏ匚w?/span>
Spring提供的另一个静态切入点?/span>RegexpMethodPointcutAdvisorQ让你可以利用正则表辑ּ来定义切入点.
使用ProxyBeanFactory可以创徏一个被通知的类Q即代理对象。它的最常用?/span>?/span>个控制行为的属性是:
1?/span>proxyInterfacesQ代理应该实现的接口列表
2?/span>interceptorNamesQ需要应用到目标对象上的通知Bean的名字。可以是拦截器?/span>Advisor或其他通知cȝ名字?/span>
注:在用容器?/span>getBeanҎӞ应该?/span>getBean(代理cȝ名字)Q而不?/span>getBean(目标对象的名?/span>)Q否?/span>AOP无法工作?/span>
getBean()
ҎQ都会生一个新的bean实例Q相当一个new的操作,对于prototype作用域的beanQ有一炚w帔R要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配|、装饰或者是装配完一?span>prototype实例后,它交给客户端,随后对该prototype实例不闻不问了。不何U作用域Q容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言QQ何配|好的析构生命周期回调方法都不会被调用。清除prototype作用域的对象q放Q何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一U可行方式是Q通过使用bean的后|处理器Q该处理器持有要被清除的bean的引用。)