一)读取Spring的配置文件applicationContext.xml几种方法
ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些,ApplicationContext则是“应用的容器”了,Spring把Bean放在这个容器中,在需要的时候,用getBean方法取出加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet。
这两者在功能上完全等同,只是一个是基于Servlet2.3版本中新引入的Listener接口实现,而另一个基于Servlet接口实现。开发中可根据目标Web容器的实际情况进行选择。
配置非常简单,在web.xml中增加:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
或:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
通过以上配置,Web容器会自动加载/WEB-INF/applicationContext.xml初始化
ApplicationContext实例,如果需要指定配置文件位置,可通过context-param加以指定:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myApplicationContext.xml</param-value>
</context-param>
配置完成之后,即可通过
WebApplicationContextUtils.getWebApplicationContext方法在Web应用中获取ApplicationContext引用。
如:ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext();
LoginAction action=(LoginAction)ctx.getBean("action");
1.利用ClassPathXmlApplicationContext
可以从classpath中读取XML文件
(1)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao)context.getBean("userDao");
(2)
ClassPathXmlApplicationContext resource = new ClassPathXmlApplicationContext(new String[]{"applicationContext-ibatis-oracle.xml","applicationContext.xml","applicationContext-data-oracle.xml"});
BeanFactory factory = resource; UserDao userDao = (UserDao) factory.getBean("userDao");
2. 利用ClassPathResource
可以从classpath中读取XML文件
Resource cr = new ClassPathResource("applicationContext.xml");
BeanFactory bf=new XmlBeanFactory(cr); UserDao userDao = (UserDao)bf.getBean("userDao");
加载一个xml文件org.springframework.beans.factory.config.PropertyPlaceholderConfigurer不起作用
3.利用XmlWebApplicationContext读取
XmlWebApplicationContext ctx = new XmlWebApplicationContext();
ctx.setConfigLocations(new String[]{"/WEB-INF/ applicationContext.xml");
ctx.setServletContext(pageContext.getServletContext());
ctx.refresh();
UserDao userDao = (UserDao ) ctx.getBean("userDao ");
}
4.利用FileSystemResource读取
Resource rs = new FileSystemResource("D:/tomcat/webapps/test/WEB-INF/classes/ applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(rs); UserDao userDao = (UserDao )factory.getBean("userDao");
值得注意的是:利用FileSystemResource,则配置文件必须放在project直接目录下,或者写明绝对路径,否则就会抛出找不到文件的异常。
5.利用FileSystemXmlApplicationContext读取
可以指定XML定义文件的相对路径或者绝对路径来读取定义文件
方法一:
String[] path={"WebRoot/WEB-INF/applicationContext.xml","WebRoot/WEB-INF/applicationContext_task.xml"};
ApplicationContext context = new FileSystemXmlApplicationContext(path);
方法二:
String path="WebRoot/WEB-INF/applicationContext*.xml"; ApplicationContext context = new FileSystemXmlApplicationContext(path);
方法三:
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:地址");
没有classpath的话就是从当前的工作目录
import java.io.File;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yaowan.ServerConfig;
import com.yaowan.framework.core.events.listener.EventListener;
/**
* @author
*
*/
public class Spring {
private static ApplicationContext appContext;
public static void init() {
appContext = new ClassPathXmlApplicationContext("file:" + ServerConfig.configPath0 + File.separator + "applicationContext.xml");
Iterator<EventListener> iterator = appContext.getBeansOfType(EventListener.class).values().iterator();
while (iterator.hasNext()) {
EventListener eventListener = (EventListener) iterator.next();
eventListener.addToEventHandlerAddListenerAdapter();
}
}
public static Object getBean(String name) {
return appContext.getBean(name);
}
public static <T> T getBean(String name, Class<T> type) {
return appContext.getBean(name, type);
}
public static <T> T getBean(Class<T> type) {
return appContext.getBean(type);
}
public static boolean containBean(String name) {
return appContext.containsBean(name);
}
public static <T> Map<String, T> getBeans(Class<T> clazz){
return appContext.getBeansOfType(clazz);
}
public static Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annoatation){
return appContext.getBeansWithAnnotation(annoatation);
}
}
Spring.getBean(CheckConfig.class).check();
// 加载配置
Spring.getBean(ConfigLoader.class).load();
<context:component-scan base-package="com.xxx.framework,com.xxx.scheduler,com.xxx.csv,com.xxx.csv.cache,com.xxx.httpserver"/>
<context:component-scan base-package="com.xxx.server.game, com.xxx.push"/>
这表示在工程项目较大的时候,划分了较多的包目录,对应的包有对应的Java模块,对应的Java模块也应用了相关的Spring的组件,在Spring容器初始化的时候,会扫描
<context:component-scanbase-package="xxxxxxxxxxxxxx"></context:component-scan>中声明的包下的标有Spring注解的类,把这些类加入到Spring容器中,在使用到这些类的时候就可以通过反射调用对应组件属性。
在类上,使用以下注解,实现bean 的声明
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Service用于标注业务层组件
@Controller用于标注控制层组件(如srping mvc的controller,struts中的action)
@Repository用于标注数据访问组件,即DAO组件
在类的成员变量上,使用以下注解,实现属性的自动装配
@Autowired: 按类的类型进行装配
@Resource(推荐) :
1】 如果同时指定了name和type,则从spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2】 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3】如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4】如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
@Resource 注解在字段上,这样就不用写 setter 方法了,并且这个注解是属于 J2EE 的,减少了与 spring 的耦合。