分类目录归档:程序生活

Program Life – Web

Spring 学习笔记–强烈推荐

/**
* 阅前说明:
* 此文件为笔者在学习Spring时所写的一些笔记

* 希望能抛砖引玉来促进大家以各种方式交流学习心得

* 如有转载,为了尊重笔者的劳动成果,请保留此段说明

* @author    贺小佼 HeXiaojiao

* Email        ld_hxj1@yahoo.com.cn

* QQ     88137099

* Time         2008-04-14 16:43:43

* Blog    http://blog.csdn.net/hexiaojiao
*/
Day-01
问题提出:
框架的主要优势是什么?
请简要描述Spring?
Spring框架分为哪几个模块,请详述?
Spring有哪些注入方式,请详细描述?

1.在Setter注入方式中,在beans包下的ProductBean中只加入一个带参数的构造方法会如何?
2.在config.xml中少加一property项会如何?
3.Spring中有哪些集合注入,如何注入?
4.问:如何设置单例模式?有什么作用和特殊效果?
5.问:什么叫混合注入模式,请举例说明?
6.问: Spring中如何进行类型数据的设置
7.问:Spring支不支持数据类型自动转换?构造器复杂情况有哪些?
8.问:如果为嵌套属性(其属性为一个类)时如果配置?(Bean的引用如果配置)
9.问:Bean初始化方案有哪几种,请详述?
10.问:在bean类中(1)初始化接口方案、(2)构造方法与(3)初始化方法方案中各方法的执行顺序如何?
//=======================================================
问题解决:
//——————————————————————-

———-  
框架的主要优势是什么?

请简要描述Spring?

Spring框架分为哪几个模块,请详述?
    答:Spring框架可分为七个模块,分别如下:
     1.核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
      2.Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
      3.Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
      4.Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
      5.Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
      6.Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 JakartaStruts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
      7.Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
//——————————————————————-

———-
Spring有哪些注入方式,请详细描述?
    答: 通过注入方式,使程序解耦合
    一。通过构造器(构造方法)注入
构造器注入操作步骤:
   1.引入Spring架包,建包ioc.common 在这包下建立三个包
   ioc.common.beans,ioc.common.config,ioc.common.logic
   2.在beans包下建立UserBean类,代码如下:

[code]//UserBean.java
   package ioc.common.beans;
public class UserBean …{
        private String userName;
        private String userPassword;

        public UserBean() …{
        }

        public UserBean(String userName, String userPassword) …{
          this.userName = userName;
          this.userPassword = userPassword;
        }

        public String getUserName() …{
          return userName;
        }

        public void setUserName(String userName) …{
          this.userName = userName;
        }

        public String getUserPassword() …{
          return userPassword;
        }

        public void setUserPassword(String userPassword) …{
          this.userPassword = userPassword;
        }

        @Override
        public String toString() …{
          return userName + "-" + userPassword;
        }
}[/code]

3.在config包下建立config.xml文件,内容如下:
[code]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
        <bean id="userBean" class="ioc.common.beans.UserBean">
          <constructor-arg index="0">
            <value>Janet </value>
          </constructor-arg>
          <constructor-arg index="1">
            <value>88888888</value>
          </constructor-arg>
        </bean>
</beans>
[/code]
4.在logic包下建立Run.java,内容如下:

[code]package ioc.common.logic;
import ioc.common.beans.UserBean;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class Run …{
        public static void main(String[] args) …{
          String fileName = "./src/ioc/common/config/config.xml";
          ApplicationContext ac = new FileSystemXmlApplicationContext

(fileName);
          // 取得一个实例
          UserBean user = (UserBean) ac.getBean("userBean");
          System.out.println(user);
        }
}
//end of Run.java[/code]

框架:有固定流程的代码集合,代码中的流程能被反复重用
    
    备注:
    1.如果构造器(方法)中没有写任何代码又会如何?
    答:将会输出 null-null,Spring不关心构造器实现何种功能,只去调用执行;
    2.如果没有这个构造器会如何?
    答:将会使Spring找不到该构造器而产生异常      
    Exception in thread “main”

org.springframework.beans.factory.BeanCreationException:
    Error creating bean with name ‘userBean’ defined in file
    

[/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xml]:
    2 constructor arguments specified but no matching constructor found in bean ‘userBean’ (hint: specify index and/or type arguments for simple parameters to avoid type ambiguities)
    3.如果构造器中有多个参数,没有配置其中某个参数会如何?如何处理?
    答:Spring将会产生找不到参数异常,处理方式:建立一个没有该参数的构造器或写入参数
    Related cause:org.springframework.beans.factory.UnsatisfiedDependencyException:Error creating bean with name ‘userBean’ defined in file[/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xml]: Unsatisfied dependency expressed through constructor argument with index 1 of type [java.lang.String]: Ambiguous constructor argument types – did you specify the correct bean references as constructor arguments?
    Context:包含特定内容的环境
/////////////////////////////////////////////Constructor IOC END    
    
二。 Set注入
    1.在步骤一的基础上,在beans包下建立ProductBean类,代码如下:

[code]  //ProductBean.java
package ioc.common.beans;
public class ProductBean …{
        private String productName;
        private String productDiscript;

        public void setProductName(String productName) …{
          this.productName = productName;
        }

        public void setProductDiscript(String productDiscript) …{
          this.productDiscript = productDiscript;
        }

        @Override
        public String toString() …{
          return productName + "-" + productDiscript;
        }
}[/code]
2.在config.xml中加入如下内容:      

[code]    <bean id="productBean" class="ioc.common.beans.ProductBean">
          <property name="productName">
            <value>Motorolla</value>
          </property>
          <property name="productDiscript">
            <value>mebophone producter</value>
          </property>
        </bean>[/code]
     3.在logic包下新建类RunConstructor代码如下

[code]     //RunSetter.java
package ioc.common.logic;

import ioc.common.beans.ProductBean;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class RunSetter …{
        public static void main(String[] args) …{
          String fileName = "./src/ioc/common/config/config.xml";
          ApplicationContext ac = new FileSystemXmlApplicationContext

(fileName);
          ProductBean product = (ProductBean) ac.getBean

("productBean");
          System.out.println(product);
        }
}[/code]
问题:
        1.在Setter注入方式中,在beans包下的ProductBean中只加入一个带参

数的构造方法会如何?
        答:将会产生异常Spring异常与JVM异常
        Exception in thread “main” org.springframework.beans.factory.BeanCreationException:
        Error creating bean with name ‘productBean’ defined in file     [/home/tarena/corejava/JSP/SpringPrj/./src/ioc/common/config/config.xml]:
        Instantiation of bean failed; nested exception is  org.springframework.beans.BeanInstantiationException:
        Could not instantiate bean class [ioc.common.beans.ProductBean]:    No default constructor found; nested exception is  java.lang.NoSuchMethodException:
        ioc.common.beans.ProductBean.()
        //JVM异常        
        Caused by: java.lang.NoSuchMethodException:ioc.common.beans.ProductBean.()
        
        Tips:强烈建议有不带参数的构造器
        
        2.在config.xml中少加一property项会如何?
        答:正常运行,但少加的属性值为null;
        
        3.Spring中有哪些集合注入,如何注入?
        答: Spring中有List,Map,Properties,Set,数组(如 String [] ,使用同List)等集合注入;
       注入方法:
       在配置文件中       或constructor-arg index=”参数序号,从0开始取”加入相应配置参数
       形如:
[code]           <list>
              <value>Eric</value>
              <value>Narci</value>
            </list>
          
            <map>
              <entry key="HR">
                <value>人力资源部</value>
              </entry>
              <entry key="MIS">
                <value>信息管理部</value>
              </entry>
            </map>
          
            <props>
              <prop key="GG">成俊杰</prop>
              <prop key="MM">伍欣</prop>
            </props>
          
            <set>
              <value>CoreJava</value>
              <value>JDBC</value>
              <value>AJAX</value>
            </set>[/code]
  ////////////// END Set注入 END
         三。 混合注入
         即构造器注入与Set注入方式混合使用
         如问题 5.
        Tips:如果同时在constractor-arg 和property标签中配置同一属性,

则Setter注入方式会覆盖构造器注入
        //—————————————————————————–  
  4.问:如何设置单例模式?有什么作用和特殊效果?
  答:在config.xml中设置
      其中singleton=”true”,设定该bean为单例模式;
      作用:调用该类的多个对象时只在第一次实例化
      特殊效果: 调用时第一次创建对象并赋值,对象还在内存中存活,在第二次或之后创建对象后不用赋值也能调用前面赋予的属性 值。
//———————————————————————-  
  5.问:什么叫混合注入模式,请举例说明?
  答:混合注入模式如:
[code] <constructor-arg index="0">
            <value>Janet </value>
          </constructor-arg>
          <property name="userPassword">
            <null />
          </property>[/code]
  这在构造器中设置用户名,而在Set注入中设置密码
//——————————————————————-

———-  
   6.问: Spring中如何进行类型数据的设置
   答:在配置文件config.xml中进行设置,在value标签中加入属性type=”类型”
  

                 500
        
//——————————————————————-

———-  
   7.问:Spring支不支持数据类型自动转换?构造器复杂情况有哪些?
   答:支持;如果构造器中参数个数与设置个数相等则调用String参数的构造器,否则自动转换类型再进行调用
        如果类型转换失败,则会输出相应出错信息。
//—————————————————————————–  
   8.问:如果为嵌套属性(其属性为一个类)时如果配置?(Bean的引用如果配置)
   答:配置属性形如:
[code] <property name="product">
          <ref bean="product"/><!–bean名为此配置文件中的另一个(引用类的)bean中id属性值–>
        </property>
        <property name="brithday">
          <ref bean="date"/>
        </property>
   <bean id="date" class="java.util.Date"></bean>   [/code]
//—————————————————————————–  
   9.问:Bean初始化方案有哪几种,请详述?
   答:有初始化接口方案和初始化方法方案;
       方案一:初始化接口方案如下:
9.问:Bean初始化方案有哪几种,请详述?
   答:有初始化接口方案和初始化方法方案;
       方案一:初始化接口方案如下:

[code]      //Bean开发:
   package init.beans;  
   public class User implements InitializingBean …{
        private String userName;
        public void afterPropertiesSet () throws Exception …{
          this.userName = "Google";
          System.out.println("++++++++++++1");
        }
        public String getUserName() …{
          return userName;
        }
        public void setUserName(String userName) …{
          this.userName = userName;
        }
    }[/code]
    //config.xml的配置没有任何特殊的地方。如下:
[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
        <bean id="userBean" class="init.beans.UserBean">      
        <property name="userName">
        <value>Eric</value>
</property>
        </bean>
</beans>[/code]

[code]//运行调用代码如下 init.logic.RunLogic.java   //Google
package init.logic;

import init.beans.UserBean;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class RunLogic …{
        public static void main(String[] args) …{
          String fileName = "./src/init/config/config.xml";
          ApplicationContext ac = new FileSystemXmlApplicationContext

(fileName);
          String beanName = "userBean";
          Object obj = ac.getBean(beanName);
          if (obj != null) …{
            UserBean user = (UserBean) obj;
            System.out.println(user.getUserName());
          }
        }
}
   //输出结果为
   //++++++++++++1
   //Google[/code]

[code]package init.logic;

import init.beans.UserBean;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class RunLogic …{
        public static void main(String[] args) …{
          String fileName = "./src/init/config/config.xml";
          ApplicationContext ac = new FileSystemXmlApplicationContext

(fileName);
          String beanName = "userBean";
          Object obj = ac.getBean(beanName);
          if (obj != null) …{
            UserBean user = (UserBean) obj;
            System.out.println(user.getUserName());
          }
        }
}
   //输出结果为
   //++++++++++++1
   //Google[/code]
方案二:初始化方法方案步骤如下:
       1.在java Bean中加入初始化方法,形如:

[code]       //init.beans.UserBean
       public String initUser() …{
          this.userName = "BaiDu";
          System.out.println("*******************2");
          return this.userName;
        }[/code]
      2.在配置文件./src/init/config/config.xml中写入如下内容:

[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
        <bean id="userBean" class="init.beans.UserBean"
          init-method="initUser">
          <property name="userName">
            <value>Eric</value>
          </property>
        </bean>
</beans>[/code]
3.在调用类执行的方法中写入如下代码:

[code]      //init.logic.RunLogic
package init.logic;

import init.beans.UserBean;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class RunLogic …{
        public static void main(String[] args) …{
          String fileName = "./src/init/config/config.xml";
          ApplicationContext ac = new FileSystemXmlApplicationContext

(fileName);
          String beanName = "userBean";
          Object obj = ac.getBean(beanName);
          if (obj != null) …{
            UserBean user = (UserBean) obj;
            System.out.println(user.getUserName());
          }
        }
}
        //得输出结果为:
        //*******************2
        //BaiDu[/code]
//—————————————————————————–  
   10.问:在bean类中(1)初始化接口方案、(2)构造方法与(3)初始化方法方案中

各方法的执行顺序如何?
        答:执行顺序:为(2)==>(1)==>(3);
        如在UserBean中加入:
[code]public UserBean() …{
          System.out.println("#######################0");
        }

        public String initUser() …{
          this.userName = "BaiDu";
          System.out.println("*******************2");
          return this.userName;
        }

        public void afterPropertiesSet() throws Exception …{
          this.userName = "Google";
          System.out.println("++++++++++++1");
        }
        //结果为:
        //#######################0
        //++++++++++++1
        //*******************2
        //BaiDu[/code]
//—————————————————————————–    
什么叫依赖注入,控制反转?    
     依赖配置文件,通过配置文件来赋值,而不是在程序中

当bean某属性为数组时(如String [])如何配置?
     答:类似List
[code]<property name="basenames">
            <list>
              <value>international.config.resources</value>
              <!– 可写多个资源文件  –>
            </list>
     </property>[/code]
//—————————————————————————–    

Day 02
1.如何对Spring进行国际化?
2.什么Spring事件模型请举例说明?
//——————————————————————-

———-    
如何对Spring进行国际化?
        1).建立资源文件
     //   src/international/config/resources_zh_CN.properties中内容如下:
    userinfo={0}\u662f\u4e00\u4e2a\u597d\u4eba
     //   src/international/config/resources_en.properties中内容如下:
     userinfo={0} is a wonderful man
        2).建立国际化配置文件 (src/international/config/config.xml)
[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
        <bean id="messageSource"         class="org.springframework.context.support.ResourceBundleMessageSource">
          <!–
          id 与 class不能改动写死在Spring中类
          FileSystemXmlApplicationContext
          的getMessage方法中了        
             –>
          <property name="basenames">
            <list>
              <value>international.config.resources</value>
              <!– 可放多套资源文件,其中basenames为String [] 类型  –>
            </list>
          </property>
        </bean>
</beans>[/code]
3).编写测试类(international.logic.Run)    
[code]
package international.logic;

import java.util.Locale;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;

public class Run …{
        public static void main(String[] args) …{
          String sourceFile = "src/international/config/config.xml";
          ApplicationContext act = new

FileSystemXmlApplicationContext(sourceFile);
          String resolvable = "userinfo";
          Object[] paramList = …{ "Eric" };
          String msg = act.getMessage(resolvable, paramList,

Locale.getDefault());
        // 如果为其他语言找不到其配置文件时,则会加载和操作系统语言一样

的资源文件
        //如果也不存在则会出现异常
        // 加载顺序 先加载指定语言资源
        // 如果失败再尝试加载操作系统语言相应的资源文件
        // 如果失败,再加载默认的资源文件
        //一旦找到符合的就不再找了
        //最后都找不到时抛出异常,不会加载此顺序外的资源文件      
          System.out.println(msg);
        }
}
[/code]
//—————————————END OF 如何对Spring进行国际化?

2.什么Spring事件模型请举例说明?
   答: 事件模型包含三类角色,事件触发者,事件和事件接受者;
        消息传递方向为,事件触发者==>事件==>事件接受者;
        事件模型建立步骤:
        1).定义事件

[code]//event.events.WarnEvent
package event.events;
import org.springframework.context.ApplicationEvent;
public class WarnEvent extends ApplicationEvent …{
private static final long serialVersionUID =

3287507907413175457L;
public WarnEvent(Object source) …{
  super(source);
}
}[/code]
        2).建立事件响应者

[code]//event.listeners.Receiver    
package event.listeners;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import event.events.WarnEvent;

public class Receiver implements ApplicationListener …{
public void onApplicationEvent(ApplicationEvent event) …{
  System.out.println("Receiver接收到事件@");
  if (true == event instanceof WarnEvent) …{
   // 对各种事件的处理
   WarnEvent we = (WarnEvent) event;
   String msg = (String) we.getSource();
   System.out.println("Receiver" + msg);
  }
}
}[/code]
[code]
//event.listeners.JaneReceiver
package event.listeners;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import event.events.WarnEvent;
public class JaneReceiver implements ApplicationListener …{
public void onApplicationEvent(ApplicationEvent event) …{
  System.out.println("JaneReceiver接收到事件@");
  if (true == event instanceof WarnEvent) …{
   // 对各种事件的处理
   WarnEvent we = (WarnEvent) event;
   long time = we.getTimestamp();
   System.out.println("time" + time);
   String msg = (String) we.getSource();
   System.out.println("JaneReceiver" + msg);
  }
}
}
[/code]
  3).建立配置文件//src/event/config/config.xml
[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"     "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="receiver" class="event.listeners.Receiver"></bean>
<bean id="janereceiver" class="event.listeners.JaneReceiver"></bean>
</beans>[/code]
  4).建立事件触发者类
[code]
package event.sender;
import org.springframework.context.ApplicationContext;
import

org.springframework.context.support.FileSystemXmlApplicationContext;
import event.events.WarnEvent;
public class Run …{
public static void main(String[] args) …{
  String sourceFile = "src/event/config/config.xml";
  ApplicationContext act = new

FileSystemXmlApplicationContext(sourceFile);
  WarnEvent event = new WarnEvent("HaHa");
  act.publishEvent(event);
}
}
[/code]
//————————————–2. END
3.问题:什么是AOP?
   答:AOP全称是Aspect-Oriented Programming,中文翻译是面向方面的编程或者面向切面的编程。

4.何谓Aspect?
   答:Aspect(切面):一个关注点的模块化,这个关注点可能会横切多个对象。
   事务管理是J2EE应用中一个关于横切关注点的很好的例子。
   在SpringAOP中,切面可以使用通用类(基于模式的风格)
   或者在普通类中以@Aspect注解(@Aspect风格)来实现。
   即:当前关注的一个代码的流程,其中可能调用了多个类的多个方法。
5.请简述AOP的意义?
   答:现在的系统往往强调减小模块之间的耦合度,AOP 技术就是用来帮助实现这一目标的。
   从某种角度上来讲“切面”是一个非常形象的描述,它好像在系统的功能之上横切一刀,   要想让系统的功能继续,就必须先过了这个切面。
   这些切面监视并拦截系统的行为,在某些(被指定的)行为执行之前或之后执行一些附加的任务(比如记录日志).
   而系统的功能流程(比如 Greeting)并不知道这些切面的存在,   更不依赖于这些切面,这样就降低了系统模块之间的耦合度。

先写这些,欢迎经常交流!

Eclipse快捷键指南

 

作用域
功能
快捷键
全局
查找并替换
Ctrl+F
文本编辑器
查找上一个
Ctrl+Shift+K
文本编辑器
查找下一个
Ctrl+K
全局
撤销
Ctrl+Z
全局
复制
Ctrl+C
全局
恢复上一个选择
Alt+Shift+↓
全局
剪切
Ctrl+X
全局
快速修正
Ctrl1+1
全局
内容辅助
Alt+/
全局
全部选中
Ctrl+A
全局
删除
Delete
全局
上下文信息
Alt+?
Alt+Shift+?
Ctrl+Shift+Space
Java编辑器
显示工具提示描述
F2
Java编辑器
选择封装元素
Alt+Shift+↑
Java编辑器
选择上一个元素
Alt+Shift+←
Java编辑器
选择下一个元素
Alt+Shift+→
文本编辑器
增量查找
Ctrl+J
文本编辑器
增量逆向查找
Ctrl+Shift+J
全局
粘贴
Ctrl+V
全局
重做
Ctrl+Y

查看
作用域
功能
快捷键
全局
放大
Ctrl+=
全局
缩小
Ctrl+-
窗口
作用域
功能
快捷键
全局
激活编辑器
F12
全局
切换编辑器
Ctrl+Shift+W
全局
上一个编辑器
Ctrl+Shift+F6
全局
上一个视图
Ctrl+Shift+F7
全局
上一个透视图
Ctrl+Shift+F8
全局
下一个编辑器
Ctrl+F6
全局
下一个视图
Ctrl+F7
全局
下一个透视图
Ctrl+F8
文本编辑器
显示标尺上下文菜单
Ctrl+W
全局
显示视图菜单
Ctrl+F10
全局
显示系统菜单
Alt+-
导航
作用域
功能
快捷键
Java编辑器
打开结构
Ctrl+F3
全局
打开类型
Ctrl+Shift+T
全局
打开类型层次结构
F4
全局
打开声明
F3
全局
打开外部javadoc
Shift+F2
全局
打开资源
Ctrl+Shift+R
全局
后退历史记录
Alt+←
全局
前进历史记录
Alt+→
全局
上一个
Ctrl+,
全局
下一个
Ctrl+.
Java编辑器
显示大纲
Ctrl+O
全局
在层次结构中打开类型
Ctrl+Shift+H
全局
转至匹配的括号
Ctrl+Shift+P
全局
转至上一个编辑位置
Ctrl+Q
Java编辑器
转至上一个成员
Ctrl+Shift+↑
Java编辑器
转至下一个成员
Ctrl+Shift+↓
文本编辑器
转至行
Ctrl+L
搜索
作用域
功能
快捷键
全局
出现在文件中
Ctrl+Shift+U
全局
打开搜索对话框
Ctrl+H
全局
工作区中的声明
Ctrl+G
全局
工作区中的引用
Ctrl+Shift+G
文本编辑
作用域
功能
快捷键
文本编辑器
改写切换
Insert
文本编辑器
上滚行
Ctrl+↑
文本编辑器
下滚行
Ctrl+↓
文件
作用域
功能
快捷键
全局
保存
Ctrl+X
Ctrl+S
全局
打印
Ctrl+P
全局
关闭
Ctrl+F4
全局
全部保存
Ctrl+Shift+S
全局
全部关闭
Ctrl+Shift+F4
全局
属性
Alt+Enter
全局
新建
Ctrl+N
项目
作用域
功能
快捷键
全局
全部构建
Ctrl+B
源代码
作用域
功能
快捷键
Java编辑器
格式化
Ctrl+Shift+F
Java编辑器
取消注释
Ctrl+\
Java编辑器
注释
Ctrl+/
Java编辑器
添加导入
Ctrl+Shift+M
Java编辑器
组织导入
Ctrl+Shift+O
Java编辑器
使用try/catch块来包围
未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。
运行
作用域
功能
快捷键
全局
单步返回
F7
全局
单步跳过
F6
全局
单步跳入
F5
全局
单步跳入选择
Ctrl+F5
全局
调试上次启动
F11
全局
继续
F8
全局
使用过滤器单步执行
Shift+F5
全局
添加/去除断点
Ctrl+Shift+B
全局
显示
Ctrl+D
全局
运行上次启动
Ctrl+F11
全局
运行至行
Ctrl+R
全局
执行
Ctrl+U
重构
作用域
功能
快捷键
全局
撤销重构
Alt+Shift+Z
全局
抽取方法
Alt+Shift+M
全局
抽取局部变量
Alt+Shift+L
全局
内联
Alt+Shift+I
全局
移动
Alt+Shift+V
全局
重命名
Alt+Shift+R
全局
重做
Alt+Shift+Y

另外,还有一个常用的快速输入System.out.println的方法,先输入一个sysout ,然后按 Alt+/ 就会自动补全了

利用java.util.Properties读取ini配置文件

转载自: http://www.hijava.org/j2se/util-properties-ini
[code]  public void getOption() {

    String OptionFile = "Option.ini";

    Properties p = new Properties();
    try {
      p.load(new FileInputStream(OptionFile));
    } catch (FileNotFoundException e) {

      e.printStackTrace();
    } catch (IOException e) {

      e.printStackTrace();
    }
    String Thread_num = p.getProperty("thread_num");
    String Pass_num = p.getProperty("pass_num");
    String Interval_time = p.getProperty("interval_time");

  }[/code]

Option.ini文件内容:

[code][option]
thread_num=2
pass_num=6
interval_time=6000[/code]

关于IT人的一个冷笑话

[color=#0000FF][size=4]男孩正走在路上,一只青蛙将他叫住,对他说:“如果你吻我,我就能变成美丽的公主。”男孩听后,弯下身,把青蛙捡起 来,放进口袋里。  
  青蛙又开口了:“如果你吻我,把我变成美丽的公主,我就和你共处一个星期。”  
  男孩吧青蛙掏出 来,冲它笑了笑,又放回口袋里。  
  于是青蛙叫起 来:“如果你吻我,把我变成美丽的公主, 我就让你为所欲为。”  
  男孩把青蛙掏出 来,冲它笑了笑,又放回口袋里。  
  最后青蛙问道:“为什么?我告诉过你我是一位美丽的公主,会与你共度一个星期并让你为所欲为。你为什么还不愿吻我?”  
  男孩说道:“我是搞IT的。我没时间交女朋友,但拥有一只会说话的青蛙简直太酷了  [/size][/color]

java获取本机mac地址

[code]public static String getMac() throws IOException
{
String command="ipconfig /all";
String mac=null;
Process proc=Runtime.getRuntime().exec(command);
BufferedReader reader=new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line=null;
while((line=reader.readLine())!=null)
{
if(line.indexOf("Physical Address")!=-1)
{
mac=line.substring(line.indexOf("Physical Address")+36, line.length());
break;
}
}
return mac;
}[/code]

Object的clone()方法

[code]class A implements Cloneable {
  // 重写Object的clone
  public Object clone() throws CloneNotSupportedException {
    return (A) super.clone();
  }

  public String toString() {
    return "Hello,World!";
  }
}

class B {
  public static void main(String[] args) throws CloneNotSupportedException {
    A x = new A();
    Object y = (A)x.clone();
    System.out.println(y.toString());
  }

}[/code]

CPL文件

转载自:http://hi.baidu.com/tylzyoudi/blog/item/b75030014e3610031c958369.html
控制面板,你了解多少。当你安装了一些应用程序后,是否感觉到你的控制面板增加了一些组件,如安装了Borland C++ Builder后,“BDE Administrator”就会进入你的控制面板,安装了QuickTime还会增加“QuickTime”组件,这些现象说明了什么,我想它只是说明了一个事实:“控制面板”是可以操纵的,你也可以控制你的控制面板,它并无什么神秘可言,哪到底如何操纵呢,这正是我今天要讨论的主题,在这里我将会带领大家有浅入深地来探讨“控制面板”这个鲜为人知的主题。我主要分3个部分来阐述:(由于文章大小的限制,我决定将其分成两章来介绍)

1、控制面板是什么,它在哪里?

2、CPL文件的真实身份

3、VCL如何提供对“控制面板”的支持

控制面板是什么,它在哪里?

控制面板是什么,它在哪儿?以前,我也很困惑,只是偶尔从一些关于“Windows系统管理”的书籍朦胧地听到关于“控制面板”的描述:“控制面板的每一项一般都会对应一个.CPL 文件,这些文件存于系统目录下,你可以指定控制面板中要显示的项目,也可以隐藏等等”关于如何实现,可能还会教给你一些通过修改注册表来达到目的,是的,这可以达到目的,但我想这只是从一个管理者地角度来看待这个问题的,如果从程序员的角度又如何的,他们的描述能解决你的问题吗?你如何利用程序来达到控制你”控制面板”的目的,你想知道吗,请听下文分解.

CPL文件的真实身份

上面提到了以“.CPL”扩展名结尾文件”,既然又与控制面板有关,哪我就来分析一下CPL文件到底是什么吧,随便找一些CPL文件,如:main.cpl,access.cpl等,我用Dumpbin测试结果如下:

C:\WINDOWS\system32>dumpbin main.cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file main.cpl

File Type: DLL(由DLL可以知道它是一个DLL文件)

C:\WINDOWS\system32>dumpbin /exports appwiz .cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file appwiz.cpl

File Type: DLL

Section contains the following exports for appwiz.dll

ordinal hint RVA name

1 0 00017926 CPlApplet

2 1 00017F05 ConfigStartMenu

......

C:\WINDOWS\system32>dumpbin /exports access.cpl

Microsoft (R) COFF Binary File Dumper Version 6.00.8168

Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

Dump of file access.cpl

File Type: DLL

Section contains the following exports for Access.dll

ordinal hint RVA name

1 0 00004B41 CPlApplet

2 1 00004B33 DebugMain

3 2 00004B30 DllRegisterServer

3 3 00004A27 DllUnregisterServer

从上面的测试结果你看到了什么,我认为至少有两点:

1、 CPL文件就是一个DLL文件

2、 CPL文件都导出了一个CPLApplet函数

这两点揭开了控制面板程序的神秘面纱,你不会再对控制面板程序是什么感到疑惑了,其实,控制面板程序就是一个须导出CPLApplet函数的DLL文件,只是挂上了CPL的后缀名而已。既然都要导出CPLApplet函数,可以想象CPLApplet这个函数的重要性,其实,不光是控制面板,只要是想加载CPL文件的其他所有应用程序都必须取得CPLApplet函数的地址然后通过调用该函数来完成相应得功能的,以下是我从MSDN得来的关于它的声明,详细信息请参考MSDN.

LONG APIENTRY CPlApplet(
HWND hwndCPl,
UINT uMsg,
LONG lParam1,
LONG lParam2
);
参数的意义
hwndCPl 激活控制面板组件应用程序的窗口句柄
uMsg 外界传入的控制消息,CPLApplet函数就是通过该消息去完成
相应的任务的
lParam1 消息参数1
lParam2 消息参数2
CPLApplet函数可以接受的控制消息一览表:

消息 描述

━━━━━━━━━━━━━━━

CPL_INIT CPL程序收到的第一个消息,在这儿通常完成控制面板组件数据及变量的初始化工作

CPL_GETCOUNT CPLApplet函数在继CPL_INIT消息之后收到的第二个消息,它使得CPLApplet函数返回该CPL文件所包含的控制面板组件数目

CPL_INQUIRE CPL_INQUIRE及下一个要介绍的CPL_NEWINQUIRE消息是所有控制面板程序的消息中最重要的两个消息,可以这样说控制面板就是利用这两个消息来取得每个组件的名称、描述及图标等信息。CPL_INQUIRE会将组件信息填入TCPLInfo的结构中,TCPLInfo结构的声明如下:

typedef struct tagCPLINFO {
int idIcon;
int idName;
int idInfo;
LONG lData;
} CPLINFO;
typedef tagCPLINFO TCPLInfo;
然后你的程序就可以利用LoadString,LoadIcon(这个API

函数已被LoadImage函数取代,不过你还是可以用)等API

函数来取得相应的信息

CPL_NEWINQUIRE

CPL_NEWINQUIRE与CPL_INQUIRE消息所完成的功能差不多,但它会将组件信息填入TNewCPLInfo结构而不是 TCPLInfo结构中,一看名称就知CPL_NEWINQUIRE较CPL_INQUIRE后出来,按照常规的思维一般应优先选择后出来得的即使用 CPL_NEWINQUIRE,但这是一个例外,TNewCPLInfo结构虽较TCPLInfo更为完整,但它所包含的资料无法缓存,所以使用 TNewCPLInfo会使开启控制面板的速度减慢,这也是微软文件上注明着”除非必要,否则请尽量以CPL_INQUIRE消息来传递组件信息”的原因

CPL_DBLCLK 当用户双击控制面板中组件的图标时就会触发CPL_DBLCLK消息来相应用户的操作,一般是开启一个对话框来供用户进行调整设定,如:”Internet 选项” 就会显示一个有关IE设置的对话框,你可以在该对话框中设置IE的一些属性

CPL_STOP 这个消息主要是提供机会给你进行善后工作的,如释放与组件相关的内存.

CPL_EXIT 这个消息是你进行善后工作的最后机会,即在应用程序调用FreeLibray函数之前时你可以进行一些善后工作,如:释放内存等

━━━━━━━━━━━━━━━

提示: 上表所列出的消息顺序也正是CPL程序收到的消息的顺序,即CPL程序是按照CPL_INIT, CPL_GETCOUNT到CPL_EXIT来完成相应的任务的.

如果你对上面的描述还感到抽象的话,下面我就已一个实际的例子来说明到底是如何建立控制面板的应用程序。

操作步骤如下:

1:建立资源文件以便在程序中使用,下图是用Borland Resoure Workshop制作ctrl.rc的情形。

图1-1 编辑资源文件

提示:1、2表示字符串与图标资源的代号,你也可以去别的名称做好后你可以利用brcc32.exe 将其编译为res资源文件命令如下:

brc32 ctrl.rc

这样将的到ctrl.res编译后的资源文件,当然你也可以直接利用Borland Resoure Workshop建立Res格式的文件,省去编译这一环节

2:打开你的BCB,通过DLL Wizard建立一个DLL工程(因为CPL程序就是DLL文件)

3:导出CPLApplet函数,这是最重要的,其它的操作和别的程序没有区别

4:从菜单中选取”Project / Options”选项,在“Project Options”选项对话框中将Application页面的“Target file extension”改为“cpl”

提示:

由于该程序不是可执行文件,所以不能按F9运行,必须通过控制面板或rundll32.exe来运行,首先将其CPL文件Copy到系统目录下,然后利用控制面板来运行或者rundll32.exe来运行,命令如下:rundll32 shell32.dll Control_RunDLL *.cpl

源程序如下:

#include

#include

#pragma hdrstop

//导入控制面板程序相关的头文件

#include

#pragma resource "ctrl.RES"

//导出CPlApplet函数

extern "C" __declspec(dllexport) LONG _stdcall CPlApplet(

HWND hwndCPl,

UINT uMsg,

LONG lParam1,

LONG lParam2

);

//实现CPlApplet函数

LONG _stdcall CPlApplet(HWND hwndCPl,UINT uMsg,LONG lParam1,LONG lParam2)

{

LPCPLINFO ptCPLInfo;

switch (uMsg)

{

case CPL_INIT:

ShowMessage("初始化数据或变量!");

return 1;

case CPL_GETCOUNT:

ShowMessage("只有一个组件!");

return 1;

case CPL_INQUIRE:

ShowMessage("设置控制面板组件资源信息!");

ptCPLInfo=(LPCPLINFO)lParam2;

//将信息填入TCPLInfo的结构中

ptCPLInfo->idName=1;

ptCPLInfo->idInfo=1;

ptCPLInfo->idIcon=2;

ptCPLInfo->lData=0;

break;

case CPL_DBLCLK:

ShowMessage("很高兴看到你!");

return 0;

case CPL_EXIT:

ShowMessage("退出控制面板程序!");

return 0;

}

return 0;

}

#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

return 1;

}

DllEntryPoint函数是所有DLL文件的入口函数,相当于可执行文件的WinMain函数,#include 语句导入Borland C++ Builder所提供的关于控制面板的相关声明,语句extern "C" __declspec(dllexport) LONG _stdcall CPlApplet(……)导出CPLApplet函数

提示:VCL如何提供对“控制面板”的支持这一节将在“控制面板知多少(续篇)”介绍

控制面板知多少(续篇)

VCL如何提供对“控制面板”的支持

上面讲了如何写原生的控制面板程序,下面我将介绍VCL是如何支持写控制面板程序的。它主要是引入了一个Ctlpanel单元及 TAppletApplication和TAppletModule类,TAppletApplication代表一个CPL文件, TAppletModule代表一个控制面板组件,在这两个类的帮助下,你可以轻松地完成控制面板程序的编码。奇怪了,你是怎么知道的,其实,只要点选 “Project / View Soure”打开项目源代码,即可发现语句”#include <Ctlpanel.hpp>”表明它引入了Ctlpanel单元,继续追踪Ctlpanel单元(即打开Ctlpanel.hpp文件),你会发现TAppletApplication 与TAppletModule的定义,它们的定义如下:

class PASCALIMPLEMENTATION TAppletApplication : public Classes::TComponent

{

typedef Classes::TComponent inherited;

private:

unsigned FControlPanelHandle;

Classes::TList* FModules;

......

};

class PASCALIMPLEMENTATION TAppletModule : public Classes::TDataModule

{

typedef Classes::TDataModule inherited;

private:

TActivateEvent FOnActivate;

TStopEvent FOnStop;

......

};

这样一步步追踪也不失为一种学习的好方法。

一个在VCL大力支持下的控制面板的程序实例:显示你的机器名

操作步骤如下:

1、选择C++ Builder的“File / New”选项,开启“New Items”对话框(如图下图所示)选择“Control Panel Application”即建立控制面板应用程序,即CPL文件。

2、属性AppletIcon中设置图标,Caption中设置标题比如:”显示你的机器名”

1、 在Activate事件填写如下代码来获取机器名

void __fastcall TAppletModule1::AppletModuleActivate(TObject *Sender,

int Data)

{

LPTSTR lpBuffer=new char[256];

LPDWord nSize= new unsigned long(256);

GetComputerName(lpBuffer,nSize);

ShowMessage("你的计算机名称:"+AnsiString(lpBuffer));

delete lpBuffer;

delete nSize;

}

控制面板知多少(续篇)

图1-2 “New Items”对话框

提示:在“Applet Module”中选择右键,将出现快捷菜单,你可以简单地完成“安装”、“删除”等功能而不必像上面的例子那样通过“批处理文件”来完成控制面板程序的编译,测试等功能

提示:如果你想自己体会一下这个程序的功能,你不必通过键盘的输入来达到目的,网站http://www.zccfamily.com/zqget/ 提供了这个程序的所有源代码“ctrl.zip”,还有上一个程序“hello.zip”你可以去下载来看一下实际的效果。

java中Set的使用

在Java中使用Set,可以方便地将需要的类型以集合类型保存在一个变量中.主要应用在显示列表.Set是一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
以下是在JAVA中使用Set的范例

[code]import java.util.*;
public class test {

/**
* @param args
*/
public static void main(String[] args) {
   // TODO Auto-generated method stub
   Set set=new HashSet();
   set.add("abc");
   set.add("cde");
   set.add("efg");
   set.add("fgh");    
   set.add("abc"); //重复的abc,set会自动将其去掉  
   System.out.println("size="+ set.size() );
    List list = new ArrayList();
    list.add("abc");
    list.add("aaa");
    list.add("fff");
    set.addAll(list); //将list中的值加入set,并去掉重复的abc
         System.out.println("size="+ set.size() );
        for( Iterator   it = set.iterator(); it.hasNext(); )
        {            
            System.out.println("value="+it.next().toString());            
        }
}  

}[/code]

java泛型学习(转载)

转载自: http://blog.csdn.net/judasf/archive/2008/04/03/2246625.aspx
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

  Java语言引入泛型的好处是安全简单。

  在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

  泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

  泛型在使用中还有一些规则和限制:

  1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

  2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

  3、泛型的类型参数可以有多个。

  4、泛型的参数类型可以使用extends语句,例如。习惯上成为“有界类型”。

  5、泛型的参数类型还可以是通配符类型。例如Class classType = Class.forName(java.lang.String);

继续阅读