??xml version="1.0" encoding="utf-8" standalone="yes"?> ApplicationContext ctx =new FileSystemXmlApplicationContext("D:/project/bean.xml");//Ҏ具体路径加蝲文g q行ExceptionAdvisorcdQ结果如下: <? xml version="1.0" encoding="gb2312" ?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="chinese" class ="Chinese" >
< property name ="friends" >
< list >
< value > 张三 </ value >
< value > 李四 </ value >
< value > 王五 </ value >
</ list >
</ property >
< property name ="score" >
< map >
< entry key ="数学" >
< value > 60 </ value >
</ entry >
< entry key ="p" >
< value > 70 </ value >
</ entry >
< entry key ="语文" >
< value > 80 </ value >
</ entry >
< entry key ="物理" >
< value > 90 </ value >
</ entry >
< entry key ="化学" >
< value > 95 </ value >
</ entry >
</ map >
</ property >
< property name ="basicInfo" >
< props >
< prop key ="w高" > 165 </ prop >
< prop key ="体重" > 45kg </ prop >
< prop key ="学历" > 大学本科 </ prop >
</ props >
</ property >
< property name ="interest" >
< set >
< value > 唱歌 </ value >
< value > 跌 </ value >
< value > 书法 </ value >
</ set >
</ property >
</ bean >
</ beans >
对应的javacMؓ:
public class Chinese implements People
{
private List friends = new ArrayList();
private Map score = new HashMap();
private Properties basicInfo = new Properties();
private Set interest = new HashSet();
// 省略对应setҎ
.
}
]]> <? xml version="1.0" encoding="gb2312" ?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="chinese" class ="Chinese" >
< property name ="friends" >
< list >
< value > 张三 </ value >
< value > 李四 </ value >
< value > 王五 </ value >
</ list >
</ property >
< property name ="score" >
< map >
< entry key ="数学" >
< value > 60 </ value >
</ entry >
< entry key ="p" >
< value > 70 </ value >
</ entry >
< entry key ="语文" >
< value > 80 </ value >
</ entry >
< entry key ="物理" >
< value > 90 </ value >
</ entry >
< entry key ="化学" >
< value > 95 </ value >
</ entry >
</ map >
</ property >
< property name ="basicInfo" >
< props >
< prop key ="w高" > 165 </ prop >
< prop key ="体重" > 45kg </ prop >
< prop key ="学历" > 大学本科 </ prop >
</ props >
</ property >
< property name ="interest" >
< set >
< value > 唱歌 </ value >
< value > 跌 </ value >
< value > 书法 </ value >
</ set >
</ property >
</ bean >
</ beans >
对应的javacMؓ:
public class Chinese implements People
{
private List friends = new ArrayList();
private Map score = new HashMap();
private Properties basicInfo = new Properties();
private Set interest = new HashSet();
// 省略对应setҎ
.
}
]]>
eg1. ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml"); //加蝲单个配置文g
eg2.
String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};
ApplicationContext ctx = new FileSystemXmlApplicationContext(locations ); //加蝲单个配置文g
eg3.
2. ClassPathXmlApplicationContext
eg1. ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
eg2.
String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};
ApplicationContext ctx = new ClassPathXmlApplication(locations);
注:其中FileSystemXmlApplicationContext和ClassPathXmlApplicationContext?span lang=EN-US>BeanFactory?/span>xml文g定位方式一hZ路径的?br> 3. XmlWebApplicationContext
eg1. ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
]]>
/** *//**
* Copyright 2007 GuangZhou Cotel Co. Ltd.
* All right reserved.
* 试异常拦截的bean
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @version 1.0
* Creation date: 2007-7-24 - 下午08:00:37
*/
public class TestBean
{
public void method1() throws Exception
{
throw new Exception("Exception happened!");
}
/** *//**
* 字W串转换为整?
* @param number 需转换的字W串
* @return 转换成的字符?br>
* @throws NumberFormatException
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* Creation date: 2007-7-24 - 下午08:05:41
*/
public int changeToNumber(String number) throws NumberFormatException
{
//当number为空或非数字Ӟ抛出NumberFormatException
int num = Integer.parseInt(number);
return num;
}
}
2. 错误日志拦截cExceptionAdvisor
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;
import java.lang.reflect.Method;
/** *//**
* Copyright 2007 GuangZhou Cotel Co. Ltd.
* All right reserved.
* 异常拦截c?
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* @version 1.0
* Creation date: 2007-7-24 - 下午08:12:25
*/
public class ExceptionAdvisor implements ThrowsAdvice
{
public static void main(String[] args)
{
TestBean bean = new TestBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(bean);
pf.addAdvice(new ExceptionAdvisor());
TestBean proxy = (TestBean) pf.getProxy();
try
{
proxy.method1();
} catch (Exception ignore)
{
}
try
{
proxy.changeToNumber("amigo");
} catch (Exception ignore)
{
}
}
/** *//**
* Ҏ知异常的处理.
* @param method
* @param args
* @param target
* @param ex
* @throws Throwable
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* Creation date: 2007-7-24 - 下午03:35:02
*/
public void afterThrowing(Method method, Object[] args, Object target,
Exception ex) throws Throwable
{
System.out.println("*************************************");
System.out.println("Error happened in class: " + target.getClass().getName());
System.out.println("Error happened in method: " + method.getName());
for (int i = 0; i < args.length; i++)
{
System.out.println("arg[" + i + "]: " + args[i]);
}
System.out.println("Exception class: " + ex.getClass().getName());
System.out.println("*************************************");
}
/** *//**
* 对NullPointerException异常的处?br>
* @param method
* @param args
* @param target
* @param ex
* @throws Throwable
* @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
* Creation date: 2007-7-24 - 下午01:17:35
*/
public void afterThrowing(Method method, Object[] args, Object target,
NullPointerException ex) throws Throwable
{
System.out.println("*************************************");
System.out.println("Error happened in class: " + target.getClass().getName());
System.out.println("Error happened in method: " + method.getName());
for (int i = 0; i < args.length; i++)
{
System.out.println("args[" + i + "]: " + args[i]);
}
System.out.println("Exception class: " + ex.getClass().getName());
System.out.println("*************************************");
}
}
************************************
Error happened in class: TestBean
Error happened in method: method1
Exception class: java.lang.Exception
*************************************
*************************************
Error happened in class: TestBean
Error happened in method: changeToNumber
arg[0]: amigo
Exception class: java.lang.NumberFormatException
*************************************
在工E中Q可ExceptionAdvisorcM为bean定义Qƈ指定要纳入其q行异常拦截的类?/p>
1. 新徏普?Java 目 MySpringTest. q个q程无需赘述? 建项目的时候将 src 目录?bin(或者classes)目录分开, 另外提示你切换透视囄时候一定要切换q去?Java 透视? 此时默认会在 Package Explorer 中选中刚才已经建好?Java Project, 但是背景为灰?
2. 首先单击一下左边的 Package Explorer 中新建的 MySpringTest 目来光亮选中, 接着点击菜单?MyEclipse -> Add Spring Capabilities..., 接着会弹出对话框 Add Spring Capabilities 提示你设|当前项目的 Spring 属?
对话框的W一可以选择全部?Spring 框架, q是最保险的做? 不过我们的例子只需要选中Spring 2.0 Core Libraries 可以了. 点击 "Next" l箋.
W二| Add Spring bean configuration file. 保持默认g变就可以? 最后点?Finish.
3. Spring 的开发没法自动生?Bean, q里大家只好手工来写? 也很? 分别复制下面的三个代? 然后?MyEclipse src 目录上点d键后选择菜单?Paste 可以生?Java cL件了.
public interface Action {
public String execute(String str);
}
public class UpperAction implements Action {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public String execute(String str) {
return (getMessage() + str).toUpperCase();
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAction {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Action bean = (Action) ctx.getBean("theAction");
System.out.println(bean.execute("Rod"));
}
}
4. 双击左侧在第2步生成的 applicationContext.xml, 然后选择菜单?Window -> Show View -> Other..., 在弹出的对话框中选择 MyEclipse Enterprise Workbench 节点下的 Spring Beans 子节Ҏ开视图 Spring Beans. 此视图讲出现在主界面的右下侧.
5. 展开此视图中?MySpringTest 父节? q中 src/applicationContext.xml 子节? 在此节点上点d键ƈ选择弹出菜单中?New Bean 来打开 Create a new Spring bean 对话? q按照下图输入对应的内容.
Bean Id: [theAction]
Bean class: [UpperAction]
接下来请单击一?Tab 面板 Properties q点d中的 Add... 按钮, 在接下来弹出?Property Wizard 对话框中按照下图输入/选择内容:
Name: [message]
Spring type: [value]
Type: [java.lang.String]
Value:[Hello_]
最后点M?Finish 按钮关闭所有向导对话框. 然后点击菜单 File -> Save. 此时可以看到 applicationContext.xml 的内容如下所C?
<?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="theAction" class="UpperAction" abstract="false"
lazy-init="default" autowire="default" dependency-check="default">
<property name="message">
<value type="java.lang.String">Hello_</value>
</property>
</bean></beans>
然后双击 Package Explorer ?MySpringTest/src/TestAction.java 打开源代? 然后点击菜单 Run -> Run As -> 1. Java Application, 如果没有错误的话会出现如下的输? 您的W一?Hello Spring q行成功?
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
HELLO_ROD
接着您就可以对着参考书l箋创徏c? 修改 applicationContext.xml 做更多的l习?
开发整?Hibernate 的关键操作点截图:
1. 在数据库览器中选择反向工程菜单;
2. 对话框的选项说明
首先学习 Spring {框架应该本着化程序员负担, 加快开发速度的原则来q行, 而不是把框架的知识点都给学习, l习一? 另外?Spring 的时候也要注意不要过渡依?Spring 框架, 注意它们的宣传语? 无R? 轻量U? 所? 除非必要, 千万不要?Spring 侵入你的代码? 例如哪些 Aware 接口, 不也是变相的侵入了你的代码嘛. q有不要Z Spring ?Spring, 明明一D代码用 new JavaBean().setUsername("xxx") q样的方式非常简l? 你非要整Z bean 的配|文件来, U属多此一? 所以无侵入只是个相Ҏ? 代码写少? 但是 bean.xml 配置文g?Spring.jar 你不能丢? 所以你已经?Spring 侵入? 而且以后xW二家公司来做个框架解析你这?XML 文g都困隑֑, 因ؓ Spring 本nq不是可替换或者热插拔? 换句话说所有用 Spring 的代码都已经被绑定到?Spring 框架? 好了, 先说一下目前了解的 Spring 的主要应用场?
1. 依赖注入, 主要是把一些需要经怿改的内容提取?Bean, 也是量能不提取׃提取, 要不然到最后那?bean.xml 增加C几千行你也就不会觉得q时候有什么方便的地方?
2. 整合 Hibernate, q个可以说是最强大最实用的功能了, 也是Z么一提到 Spring 后面L跟着 Hibernate 的原? 在文档的 12.2. Hibernate 有相关的介绍. 例如看看下面的调用代?
import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.Testuser;
import dao.TestuserDAO;
// 调用 Hibernate DAO
public class Test {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
TestuserDAO dao =(TestuserDAO)context.getBean("userDAO");
Testuser user = new Testuser();
// user.setxxx..., 讄?
dao.save(user);
}
}
再看 DAO 的代?
package dao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Data access object (DAO) for domain model class Testuser.
*/
public class TestuserDAO extends HibernateDaoSupport {
public void save(Testuser transientInstance) {
getHibernateTemplate().save(transientInstance);
}
public void delete(Testuser persistentInstance) {
getHibernateTemplate().delete(persistentInstance);
}
}
是不是感觉简单到令h难以|信? 要保存的实体 POJO 也很?
package dao;
/**
* Testuser generated by MyEclipse Persistence Tools
*/
public class Testuser implements java.io.Serializable {
// Fields
private Integer id;
private String username;
private Integer age;
getXXX();
setXXX();
}
然后我们看主要的配置文g applicationContext.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="userDAO" class="dao.TestuserDAO">
<property name="sessionFactory">
<ref bean="hibernateSessionFactory" />
</property>
</bean>
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="file:src/hibernate.cfg.xml">
</property>
</bean>
</beans>
大家可以看到 DAO ?nbsp; HibernateSessionFactory 完全是配|出来的, 不用我们写一?Hibernate 初始化的代码, Spring 已经帮我们做好了一? 完整的代码大家可以下载附? 但是大家也请注意, 我们的代码这样做也是依赖?Spring 的框? 其实功能强大和不依赖具体的框架本w就是个谬论, 你不?依赖)它的框架又怎么能用到它的强大的功能?
3. 使用 JDBCTemplate 化普通的 JDBC 代码~写, q个大家可以ȝ参考文?官方?Spring Framework 开发参考手? 中英文均? " W?11 ?使用JDBCq行数据讉K", 老师也介l过?
4. 整合 Struts, 也参考文档里的内? 具体?15.4. Struts., ?Struts ?Action 可以被注入内?
5. AOP 功能, 我没用过, 只是听一些朋友介l说他们用的? 所以徏议大家了解一? 个h觉得挺难理解, 开发的时候也是完全依?Spring ?API, 比较隑ց. AOP ?Spring 后来加入的内? 按照官方文档?锦上添花的内?, 其实是捆绑了自q AOP, ?Spring 最核心的内容当属依赖注入功?
6. 事务理, 据说有一些h在用. 但是感觉开发v来挺费劲? 不如 EJB 3 的标注来的简? 不过你被l在?Spring 框架? 一般就只好用它自己做的q些个功能了.
7. 其它?Spring MVC {内? 都是可选项, 具体来说开发工h持上q不?Struts 来的那么直接好用.
至于 Spring 的缺?
1. 不支持分布式讉K,分布式事务和集群, q些?EJB 3 的优? 但是 Spring 目前q不支持;
2. 配置使用 XML 文g, 如果文g内容很多的话对维护的人来说是个负?
3. 提供 Spring 容器的只有一家公?Interface21), 换句话说它是非标准的, 被个别公司垄断的技? 不能?EJB 那样可以换一家厂商的服务? Spring 不存在第二家公司来做.
另外开发工L支持? MyEclipse 5 可以快速的 5 分钟做?Spring 整合 Hibernate 的框架代? 如果大家有兴可以自己找点资料来看或者直接咨询我.
那么大家看了q篇文档希望能有一些自qx, 把内?100% 掌握是不现实? 而且q了一阵子不用p定会? 所以现在需要的是了解概? 能跑一些基的代码以后用到的话再深入研究.
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
public class ExecuteAStatement {
private JdbcTemplate jt;
private DataSource dataSource;
public void doExecute() {
jt = new JdbcTemplate(dataSource);
jt.execute("create table mytable (id integer, name varchar(100))");
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
q个是普通的 Java c? 再参?11.2.4. DataSource接口, q里的另一个代码片?
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");
当然上面的连接方式可以配|成我们评里面介绍?MyEclipse Derby 的数据库q接:
org.apache.derby.jdbc.ClientDriver
jdbc:derby://localhost:1527/myeclipse;create=true
app
app
我们可以写一个测试类来执行代?
import org.springframework.jdbc.datasource.DriverManagerDataSource;
public class TestTemplate {
public static void main(String[] args) {
// 新徏一个数据源对象
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");
// 新徏一个ExecuteAStatement 对象
ExecuteAStatement eas = new ExecuteAStatement();
// l执行表辑ּ的对象关联数据源(也就是常说的注入, 通过 JavaBean ?setXxx Ҏ兌h)
eas.setDataSource(dataSource);
// 执行功能代码
eas.doExecute();
}
}
q个代码可以跑? 是普通的~程方式, 大家可以ȝ刚才介绍的文档附q的详细说明.
那么如果?Spring 来做, 代码会变成这?
ExecuteAStatement cM码保持不? 多了?beans.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="userDAO" class="ExecuteAStatement">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
</bean>
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:hsql://localhost:</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
</beans>
试c?
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
ExecuteAStatement eas =(ExecuteAStatement)context.getBean("userDAO");
// 执行功能代码
eas.doExecute();
}
}
和上面的 TestTemplate cȝ? ׃发现 new DriverManagerDataSource() q个q程不用我们写了, q行的时候会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement ?dataSource q个属性被注入?
那么q个q程到底该如何理解呢? Spring 是一个对象池, 可以化ؓ一?Map, 存多个主键和对象的映? 那么 Spring q行的过E中, 会根?beans.xml 一步步q行必要的解析工?
Map springEngine = new HashMap();
OK, 解析C
<bean id="userDAO" class="ExecuteAStatement">, 发现 bean 定义, 那就新徏一个实例存到对象池里吧, 主键是 userDAO, 值就是对?
ExecuteAStatement bean1 = new ExecuteAStatement();
springEngine.put("userDAO", bean1);
再往下执? 发现 property 定义:
<property name="dataSource">
Cq里, q道应该调?bean1.setDataSource(DataSource) Ҏ? 可以接着执行, 发现
<ref bean="myDataSource" />, ? q个Ҏ的参数还没有? 是个 bean 的引? 好了, 要调用这个方? q是?new 一个名字ؓ myDataSource ?bean2 ? pC面寻?myDataSource 的定? 扑ֈ?
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:hsql://localhost:</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
像以前一? 先实例化q个c? 然后看到 property 表情p用对应的 setXxx() q样的方? 相当于下面一D代?
// 新徏一个数据源对象
DriverManagerDataSource bean2 = new DriverManagerDataSource();
bean2.setDriverClassName("org.hsqldb.jdbcDriver");
bean2.setUrl("jdbc:hsqldb:hsql://localhost:");
bean2.setUsername("sa");
bean2.setPassword("");
不是q有?bean ?id 名字?myDataSource ? 那就把它存到对象池里?
springEngine.put("myDataSource", bean2);
好了, 最后就是把他们两个兌h? 通过 ref 里指定的 bean id 名来兌h:
// 省略cd转换的代?br>springEngine.get("userDAO").setDataSource(springEngine.get("myDataSource"));
最后返回给用户的就是一个对象池(一?Map)? 所以别用的时? 发?springEngine.get("userDAO") 回来的类?dataSource 属性已l被实例化过? q些都是 Spring q后工作的代? 通过反射机制来实?
所以最后写代码调用:
context.getBean("userDAO") 的时? 得到的是 ExecuteAStatement, q时候还有一?myDataSource, 也可以被调用:
context.getBean("myDataSource"), 得到的是 DriverManagerDataSource.
介绍的过E? 仅供参? Ƣ迎大家交流更好的原理介l文?
再{一别人推荐的通俗易懂的说? 非实现方面的:
IoC是Inversion of ControlQ控制反转。在Java开发中QIoC意味着你设计好的cMl系l去控制Q而不是在你的cd部控制。这UCؓ控制反{?
下面我们以几个例子来说明什么是IoC
假设我们要设计一个Girl和一个Boyc,其中Girl有kissҎQ即Girl惌Kiss一个Boy。那么,我们的问题是QGirl如何能够认识q个BoyQ?
在我们中国,常见的MM与GG的认识方式有以下几种
1 青梅竚wQ?2 亲友介绍Q?3 父母包办
那么哪一U才是最好呢Q?
青梅竚wQGirl从小q道自qBoy?
public class Girl {
void kiss(){
Boy boy = new Boy();
}
}
然而从开始就创徏的Boy~点是无法在更换。ƈ且要负责Boy的整个生命周期。如果我们的Girl惌换一个怎么办?Q严重不支持Girll常更换Boy,#_#Q?
亲友介绍Q由中间责提供Boy来见?
public class Girl {
void kiss(){
Boy boy = BoyFactory.createBoy();
}
}
亲友介绍Q固然是好。如果不满意Q尽另外换一个好了。但是,亲友BoyFactoryl常是以Singleton的Ş式出玎ͼ不然是Q存在于GlobalsQ无处不在,无处不能。实在是太繁琐了一点,不够灉|。我Z么一定要q个亲友掺和q来呢?Z么一定要付给她介l费呢?万一最好的朋友׃了我的男朋友呢?
父母包办Q一切交l父母,自己不用费吹C力,只需要等着Kiss好了?
public class Girl {
void kiss(Boy boy){
// kiss boy
boy.kiss();
}
}
WellQ这是对Girl最好的ҎQ只要想办法贿赂了Girl的父母,q把Boy交给他。那么我们就可以L的和Girl来Kiss了。看来几千年传统的父母之命还真是有用哦。至Boy和Girl不用自己瞎忙乎了?
q就是IOCQ将对象的创建和获取提取到外部。由外部容器提供需要的lg?
我们知道好莱坞原则:“Do not call us, we will call you.” 意思就是,You, girlie, do not call the boy. We will feed you a boy?
我们q应该知道依赖倒{原则?Dependence Inversion PrincinpleQDIP
Eric Gamma_要面向抽象编E。面向接口编E是面向对象的核心?
lg应该分ؓ两部分,?Service, 所提供功能的声?Implementation, Service的实?
好处是:多实现可以Q意切换,防止 “everything depends on everything” 问题Q即具体依赖于具体?
所以,我们的Boy应该是实现Kissable接口。这样一旦Girl不想kiss可恶的Boy的话Q还可以kiss可爱的kitten和慈的grandmother?
二、IOC的type
IoC的Type指的是Girl得到Boy的几U不同方式。我们逐一来说明?
IOC type 0Q不用IOC
public class Girl implements Servicable {
private Kissable kissable;
public Girl() {
kissable = new Boy();
}
public void kissYourKissable() {
kissable.kiss();
}
}
Girl自己建立自己的BoyQ很难更换,很难׃nl别人,只能单独使用Qƈ负责完全的生命周期?
IOC type 1Q先看代码:代码
public class Girl implements Servicable {
Kissable kissable;
public void service(ServiceManager mgr) {
kissable = (Kissable) mgr.lookup(“kissable”);
}
public void kissYourKissable() {
kissable.kiss();
}
}
q种情况出现于Avalon Framework。一个组件实CServicable接口Q就必须实现serviceҎQƈ传入一个ServiceManager。其中会含有需要的其它lg。只需要在serviceҎ中初始化需要的Boy?
另外QJ2EE中从Context取得对象也属于type 1。它依赖于配|文件?
IOC type 2Q?
public class Girl {
private Kissable kissable;
public void setKissable(Kissable kissable) {
this.kissable = kissable;
}
public void kissYourKissable() {
kissable.kiss();
}
}
Type 2出现于Spring FrameworkQ是通过JavaBean的setҎ来将需要的Boy传递给Girl。它必须依赖于配|文件?
IOC type 3:
public class Girl {
private Kissable kissable;
public Girl(Kissable kissable) {
this.kissable = kissable;
}
public void kissYourKissable() {
kissable.kiss();
}
}
q就是PicoContainer的组?。通过构造函C递BoylGirl
PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy.class);
container.registerComponentImplementation(Girl.class);
Girl girl = (Girl) container.getComponentInstance(Girl.class);
girl.kissYourKissable();
参考资?
1 http://www.picocontainer.org/presentations/JavaPolis2003.ppt
http://www.picocontainer.org/presentations/JavaPolis2003.pdf
2 DIPQ?Robert C Martin, Bob大叔的优U论文
http://www.objectmentor.com/resources/articles/dip.pdf
3 Dependency Injection 依赖注射QMatrin Fowler对DIP的扩?
http://www.martinfowler.com/articles/injection.html
4 IOC框架
PicoContainer 优秀的IOC框架
http://picocontainer.org/
Avalon
http://avalon.apache.org/
Spring Framework
http://www.springframework.org/
HiveMind
http://jakarta.apache.org/commons/hivemind
----
IoC是一U模?
IoC(Inversion of Control)中文译ؓ控制反{Q目前JavaC中流行的各种轻量U容器的实现都是以IoC模式作ؓ基础的。控制反转意味着在系l开发过E中Q设计的cd交由容器LӞ而不是在cȝ内部LӞcMcM间的关系交由容器处?一个类在需要调用另一个类?只要调用另一个类在容器中注册的名字就可以得到q个cȝ实例,与传l的~程方式有了很大的不?”不用你找,我来提供l你”,q就是控制反转的含义。Martin Fowler在他的一文章中lIoC起了一个更为直观的名字Q依赖注DI(Dependency Injection)。下面先引入q个模式?
在设计模式中Q我们已l习惯一U思维~程方式QInterface Driven Design 接口驱动Q接口驱动有很多好处Q可以提供不同灵zȝ子类实现Q增加代码稳定和健壮性等{,但是接口一定是需要实现的Q也是如下语句q早要执行:
InterfaceA a = new InterfaceAImp()Q?
InterfaceAImp是接口InterfaceA的一个子c,IoC模式可以延缓接口的实玎ͼҎ需要实玎ͼ有个比喻Q接口如同空的模型套Q在必要Ӟ需要向模型套注石膏,q样才能成ؓ一个模型实体,因此Q我们将Zؓ控制接口的实现成为注。IoC模式是解册用者和被调用者之间的一U关p,上述InterfaceA实现语句表明当前是在调用被调用者InterfaceAImpQ由于被调用者名U写入了调用者的代码中,q生了一个接口实现的原罪Q彼此联p,调用者和被调用者有紧密联系Q在UML中是用依?Dependency 表示。但是这U依赖在分离x的思维下是不可忍耐的Q必dԌ实现调用者和被调用者解耦,新的Ioc模式依赖注射 (Dependency Injection)模式由此产生了,也就是将依赖先剥,然后在适当时候再注射q入?
首先学习 Spring {框架应该本着化程序员负担, 加快开发速度的原则来q行, 而不是把框架的知识点都给学习, l习一? 另外?Spring 的时候也要注意不要过渡依?Spring 框架, 注意它们的宣传语? 无R? 轻量U? 所? 除非必要, 千万不要?Spring 侵入你的代码? 例如哪些 Aware 接口, 不也是变相的侵入了你的代码嘛. q有不要Z Spring ?Spring, 明明一D代码用 new JavaBean().setUsername("xxx") q样的方式非常简l? 你非要整Z bean 的配|文件来, U属多此一? 所以无侵入只是个相Ҏ? 代码写少? 但是 bean.xml 配置文g?Spring.jar 你不能丢? 所以你已经?Spring 侵入? 而且以后xW二家公司来做个框架解析你这?XML 文g都困隑֑, 因ؓ Spring 本nq不是可替换或者热插拔? 换句话说所有用 Spring 的代码都已经被绑定到?Spring 框架? 好了, 先说一下目前了解的 Spring 的主要应用场?
1. 依赖注入, 主要是把一些需要经怿改的内容提取?Bean, 也是量能不提取׃提取, 要不然到最后那?bean.xml 增加C几千行你也就不会觉得q时候有什么方便的地方?
2. 整合 Hibernate, q个可以说是最强大最实用的功能了, 也是Z么一提到 Spring 后面L跟着 Hibernate 的原? 在文档的 12.2. Hibernate 有相关的介绍. 例如看看下面的调用代?
import java.io.IOException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.Testuser;
import dao.TestuserDAO;
// 调用 Hibernate DAO
public class Test {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
TestuserDAO dao =(TestuserDAO)context.getBean("userDAO");
Testuser user = new Testuser();
// user.setxxx..., 讄?
dao.save(user);
}
}
再看 DAO 的代?
package dao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Data access object (DAO) for domain model class Testuser.
*/
public class TestuserDAO extends HibernateDaoSupport {
public void save(Testuser transientInstance) {
getHibernateTemplate().save(transientInstance);
}
public void delete(Testuser persistentInstance) {
getHibernateTemplate().delete(persistentInstance);
}
}
是不是感觉简单到令h难以|信? 要保存的实体 POJO 也很?
package dao;
/**
* Testuser generated by MyEclipse Persistence Tools
*/
public class Testuser implements java.io.Serializable {
// Fields
private Integer id;
private String username;
private Integer age;
getXXX();
setXXX();
}
然后我们看主要的配置文g applicationContext.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="userDAO" class="dao.TestuserDAO">
<property name="sessionFactory">
<ref bean="hibernateSessionFactory" />
</property>
</bean>
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="file:src/hibernate.cfg.xml">
</property>
</bean>
</beans>
大家可以看到 DAO ?nbsp; HibernateSessionFactory 完全是配|出来的, 不用我们写一?Hibernate 初始化的代码, Spring 已经帮我们做好了一? 完整的代码大家可以下载附? 但是大家也请注意, 我们的代码这样做也是依赖?Spring 的框? 其实功能强大和不依赖具体的框架本w就是个谬论, 你不?依赖)它的框架又怎么能用到它的强大的功能?
3. 使用 JDBCTemplate 化普通的 JDBC 代码~写, q个大家可以ȝ参考文?官方?Spring Framework 开发参考手? 中英文均? " W?11 ?使用JDBCq行数据讉K", 老师也介l过?
4. 整合 Struts, 也参考文档里的内? 具体?15.4. Struts., ?Struts ?Action 可以被注入内?
5. AOP 功能, 我没用过, 只是听一些朋友介l说他们用的? 所以徏议大家了解一? 个h觉得挺难理解, 开发的时候也是完全依?Spring ?API, 比较隑ց. AOP ?Spring 后来加入的内? 按照官方文档?锦上添花的内?, 其实是捆绑了自q AOP, ?Spring 最核心的内容当属依赖注入功?
6. 事务理, 据说有一些h在用. 但是感觉开发v来挺费劲? 不如 EJB 3 的标注来的简? 不过你被l在?Spring 框架? 一般就只好用它自己做的q些个功能了.
7. 其它?Spring MVC {内? 都是可选项, 具体来说开发工h持上q不?Struts 来的那么直接好用.
至于 Spring 的缺?
1. 不支持分布式讉K,分布式事务和集群, q些?EJB 3 的优? 但是 Spring 目前q不支持;
2. 配置使用 XML 文g, 如果文g内容很多的话对维护的人来说是个负?
3. 提供 Spring 容器的只有一家公?Interface21), 换句话说它是非标准的, 被个别公司垄断的技? 不能?EJB 那样可以换一家厂商的服务? Spring 不存在第二家公司来做.
另外开发工L支持? MyEclipse 5 可以快速的 5 分钟做?Spring 整合 Hibernate 的框架代? 如果大家有兴可以自己找点资料来看或者直接咨询我.
那么大家看了q篇文档希望能有一些自qx, 把内?100% 掌握是不现实? 而且q了一阵子不用p定会? 所以现在需要的是了解概? 能跑一些基的代码以后用到的话再深入研究.