spring的aware們

Aware是什么

spring框架提供了多個(gè)*Aware接口骤铃,用于輔助Spring Bean編程訪問(wèn)Spring容器应役。
通過(guò)實(shí)現(xiàn)這些接口荒给,可以增強(qiáng)Spring Bean的功能秋柄,將一些特殊的spring內(nèi)部bean暴露給業(yè)務(wù)應(yīng)用庸队。

  • ApplicationContextAware

將ApplicationContext暴露出來(lái)积蜻,使用最頻繁的api為getBean方法,動(dòng)態(tài)獲取spring中的bean彻消。spring2.5+之后可以不實(shí)現(xiàn)aware接口竿拆,直接@autowired注入到業(yè)務(wù)bean中直接使用。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver 
  • BeanFactoryAware

將BeanFactory暴露給用戶宾尚,也可以直接@autowired注入丙笋。BeanFactory只聲明了一些基本方法,如getBean,containsBean不见,isPrototype澳化,isSingleton等,ApplicationContext繼承了BeanFactory稳吮,它有自己的很多擴(kuò)展方法(容器啟動(dòng)日期缎谷,容器id,他還實(shí)現(xiàn)了事件接口灶似,可以發(fā)布事件等等)列林。

  • ApplicationEventPublisherAware

ApplicationEventPublisher可以發(fā)布事件,ApplicationContext也繼承了該接口酪惭,可以直接使用ApplicationContext來(lái)發(fā)布希痴。spring使用示例:

在使用Spring的事件支持時(shí),我們需要關(guān)注以下幾個(gè)對(duì)象:

  1. ApplicationEvent:繼承自EventObject春感,同時(shí)是spring的application中事件的父類砌创,需要被自定義的事件繼承。 
  2. ApplicationListener:繼承自EventListener鲫懒,spring的application中的監(jiān)聽(tīng)器必須實(shí)現(xiàn)的接口嫩实,需要被自定義的監(jiān)聽(tīng)器實(shí)現(xiàn)其onApplicationEvent方法 
  3. ApplicationEventPublisherAware:在spring的context中希望能發(fā)布事件的類必須實(shí)現(xiàn)的接口,該接口中定義了設(shè)置ApplicationEventPublisher的方法窥岩,由ApplicationContext調(diào)用并設(shè)置甲献。在自己實(shí)現(xiàn)的ApplicationEventPublisherAware子類中,需要有ApplicationEventPublisher屬性的定義颂翼。 
  4. ApplicationEventPublisher:spring的事件發(fā)布者接口晃洒,定義了發(fā)布事件的接口方法publishEvent。因?yàn)锳pplicationContext實(shí)現(xiàn)了該接口朦乏,因此spring的ApplicationContext實(shí)例具有發(fā)布事件的功能(publishEvent方法在AbstractApplicationContext中有實(shí)現(xiàn))球及。在使用的時(shí)候,只需要把ApplicationEventPublisher的引用定義到ApplicationEventPublisherAware的實(shí)現(xiàn)中呻疹,spring容器會(huì)完成對(duì)ApplicationEventPublisher的注入桶略。 

在spring的bean配置中,因?yàn)槭录怯墒录窗l(fā)出的诲宇,不需要注冊(cè)為bean由spring容器管理。所以在spring的配置中惶翻,只需配置自定義的ApplicationEventListener和publisherAware(即實(shí)現(xiàn)了ApplicationEventPublisherAware接口的發(fā)布類)姑蓝,而對(duì)于ApplicationEventPublisher的管理和注入都由容器來(lái)完成。

基于spring的事件簡(jiǎn)單實(shí)現(xiàn)如下:
定義ApplicationEvent

import org.springframework.context.ApplicationEvent;  
/** 
 * 定義Spring容器中的事件吕粗,與java普通的事件定義相比纺荧,只是繼承的父類不同而已,在 
 * 在定義上并未有太大的區(qū)別,畢竟ApplicationEvent也是繼承自EventObject的宙暇。 
 */  
public class MethodExecutionEvent extends ApplicationEvent {  
  
    private static final long serialVersionUID = 2565706247851725694L;  
    private String methodName;  
    private MethodExecutionStatus methodExecutionStatus;  
      
    public MethodExecutionEvent(Object source) {  
        super(source);  
    }  
      
    public MethodExecutionEvent(Object source, String methodName, MethodExecutionStatus methodExecutionStatus) {  
        super(source);  
        this.methodName = methodName;  
        this.methodExecutionStatus = methodExecutionStatus;  
    }  
  
    public String getMethodName() {  
        return methodName;  
    }  
  
    public void setMethodName(String methodName) {  
        this.methodName = methodName;  
    }  
  
    public MethodExecutionStatus getMethodExecutionStatus() {  
        return methodExecutionStatus;  
    }  
  
    public void setMethodExecutionStatus(MethodExecutionStatus methodExecutionStatus) {  
        this.methodExecutionStatus = methodExecutionStatus;  
    }  
}  

定義ApplicationEventListener

import org.springframework.context.ApplicationEvent;  
import org.springframework.context.ApplicationListener;  
  
import com.nuc.event.MethodExecutionEvent;  
import com.nuc.event.MethodExecutionStatus;  
/** 
 * Spring容器中的事件監(jiān)聽(tīng)器输枯,與java中基本的事件監(jiān)聽(tīng)器的定義相比,這里需要實(shí)現(xiàn)ApplicationListener接口 
 * ApplicationListener接口雖然繼承自EventListener占贫,但擴(kuò)展了EventListener 
 * 它在接口聲明中定義了onApplicationEvent的接口方法桃熄,而不像EventListener只作為標(biāo)記性接口。 
 */  
  
public class MethodExecutionEventListener implements ApplicationListener {  
  
    public void onApplicationEvent(ApplicationEvent event) {  
        if (event instanceof MethodExecutionEvent) {  
           if (MethodExecutionStatus.BEGIN  
                    .equals(((MethodExecutionEvent) event)  
                            .getMethodExecutionStatus())) {  
                System.out.println("It's beginning");  
            }  
            if (MethodExecutionStatus.END.equals(((MethodExecutionEvent) event).getMethodExecutionStatus())) {  
                System.out.println("It's ending");  
            }  
        }  
    }  
}  

定義ApplicationEventPublisherAware

import org.springframework.context.ApplicationEventPublisher;  
import org.springframework.context.ApplicationEventPublisherAware;  
  
import com.nuc.event.MethodExecutionEvent;  
import com.nuc.event.MethodExecutionStatus;  
  
public class MethodExecutionEventPublisher implements  
        ApplicationEventPublisherAware {  
  
    private ApplicationEventPublisher eventPublisher;  
      
    public void methodToMonitor() {  
        MethodExecutionEvent beginEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.BEGIN);  
        this.eventPublisher.publishEvent(beginEvent);  
        //TODO  
        MethodExecutionEvent endEvent = new MethodExecutionEvent(this, "methodToMonitor", MethodExecutionStatus.END);  
        this.eventPublisher.publishEvent(endEvent);  
    }  
      
    public void setApplicationEventPublisher(  
            ApplicationEventPublisher applicationEventPublisher) {  
        this.eventPublisher = applicationEventPublisher;  
    }  
}  

定義bean配置

<?xml version="1.0" encoding="GBK"?>  
<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"  
    default-autowire="byName">  
    <bean id="methodExecListener" class="com.nuc.listener.MethodExecutionEventListener"></bean>  
    <bean id="evtPublisher" class="com.nuc.publisher.MethodExecutionEventPublisher"></bean>   
</beans>  

使用事件

import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
import com.nuc.publisher.MethodExecutionEventPublisher;  
  
public class App   
{  
    public static void main( String[] args )  
    {  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        MethodExecutionEventPublisher publisher = (MethodExecutionEventPublisher)context.getBean("evtPublisher");  
        publisher.methodToMonitor();  
    }  
} 
  • BeanClassLoaderAware

實(shí)現(xiàn)該aware后spring會(huì)把加載業(yè)務(wù)bean類時(shí)使用的類加載器暴露出來(lái)型奥。接口聲明如下:

public interface BeanClassLoaderAware extends Aware {

    /**
     * Callback that supplies the bean {@link ClassLoader class loader} to
     * a bean instance.
     * <p>Invoked <i>after</i> the population of normal bean properties but
     * <i>before</i> an initialization callback such as
     * {@link InitializingBean InitializingBean's}
     * {@link InitializingBean#afterPropertiesSet()}
     * method or a custom init-method.
     * @param classLoader the owning class loader; may be {@code null} in
     * which case a default {@code ClassLoader} must be used, for example
     * the {@code ClassLoader} obtained via
     * {@link org.springframework.util.ClassUtils#getDefaultClassLoader()}
     */
    void setBeanClassLoader(ClassLoader classLoader);

}
  • BeanNameAware

將當(dāng)前bean在spring中的beanname暴露出來(lái)瞳收。

lic interface BeanNameAware extends Aware {

    /**
     * Set the name of the bean in the bean factory that created this bean.
     * <p>Invoked after population of normal bean properties but before an
     * init callback such as {@link InitializingBean#afterPropertiesSet()}
     * or a custom init-method.
     * @param name the name of the bean in the factory.
     * Note that this name is the actual bean name used in the factory, which may
     * differ from the originally specified name: in particular for inner bean
     * names, the actual bean name might have been made unique through appending
     * "#..." suffixes. Use the {@link BeanFactoryUtils#originalBeanName(String)}
     * method to extract the original bean name (without suffix), if desired.
     */
    void setBeanName(String name);

}

Spring 自動(dòng)調(diào)用。并且會(huì)在Spring自身完成Bean配置之后厢汹,且在調(diào)用任何Bean生命周期回調(diào)(初始化或者銷毀)方法之前就調(diào)用這個(gè)方法螟深。換言之,在程序中使用BeanFactory.getBean(String beanName)之前烫葬,Bean的名字就已經(jīng)設(shè)定好了界弧。所以,程序中可以盡情的使用BeanName而不用擔(dān)心它沒(méi)有被初始化搭综。

  • BootstrapContextAware,資源適配器,不知道怎么用
  • EmbeddedValueResolverAware

應(yīng)用配置文件讀取輔助月匣。他的讀取方式需要加${xx.xx}這樣的方式,使用示例:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;

@Component("propertiesUtils")
public class PropertiesUtils implements EmbeddedValueResolverAware {

    private StringValueResolver resolver = null;

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = resolver;
    }

    public String getPropertiesValue(String name) {
        return resolver.resolveStringValue(name);
    }
}

測(cè)試:

import com.google.common.collect.Maps;
import com.jd.caiyu.common.utils.PropertiesUtils;
import com.jd.caiyu.match.domain.agent.enums.AgentTypeEnum;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Map;

import static com.jd.caiyu.match.domain.agent.enums.AgentTypeEnum.PRIMARY;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-config.xml")
public class PropertiesUtilsTest {

    @Autowired
    private PropertiesUtils propertiesUtils;

    @Test
    public void testGetValue(){
        String value = propertiesUtils.getPropertiesValue("${jmq.address}"); //注意訪問(wèn)方式

        Assert.assertEquals("查詢結(jié)果與期待的不一致7茏恕3!", "192.168.179.66:50088", value);



        Map<AgentTypeEnum, String> map = Maps.newHashMap();

        map.put(PRIMARY, "xxx");
    }

}
  • EnvironmentAware
    Environment可以獲取所有環(huán)境變量称诗,包括應(yīng)用的properties萍悴,使用示例:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
 
/**
 * 主要是@Configuration癣诱,實(shí)現(xiàn)接口:EnvironmentAware就能獲取到系統(tǒng)環(huán)境信息
 */
@Configuration
public class MyEnvironmentAware implements EnvironmentAware{
 
       //注入application.properties的屬性到指定變量中.
       @Value("${spring.datasource.url}")
       private String myUrl;
      
       /**
        *注意重寫(xiě)的方法 setEnvironment 是在系統(tǒng)啟動(dòng)的時(shí)候被執(zhí)行。
        */
       @Override
       public void setEnvironment(Environment environment) {
             
              //打印注入的屬性信息.
              System.out.println("myUrl="+myUrl);
             
              //通過(guò) environment 獲取到系統(tǒng)屬性.
              System.out.println(environment.getProperty("JAVA_HOME"));
             
              //通過(guò) environment 同樣能獲取到application.properties配置的屬性.
              System.out.println(environment.getProperty("spring.datasource.url"));
             
              //獲取到前綴是"spring.datasource." 的屬性列表值.
              RelaxedPropertyResolver relaxedPropertyResolver = new RelaxedPropertyResolver(environment, "spring.datasource.");
              System.out.println("spring.datasource.url="+relaxedPropertyResolver.getProperty("url"));
       System.out.println("spring.datasource.driverClassName="+relaxedPropertyResolver.getProperty("driverClassName"));
       }
}

ApplicationContext也繼承了該接口吆寨,所以可以直接使用ApplicationContext赏淌。
國(guó)際化使用示例:

首先定義一個(gè)messageSource:


<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <!-- 資源國(guó)際化測(cè)試 --> 
    <bean id="messageSource"        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">        <property name="basenames"> 
            <list> 
                <value>org/rjstudio/spring/properties/messages</value> 
            </list> 
        </property> 
    </bean> 
</beans> 

這個(gè)Bean的id是定死的,只能為“messageSource”啄清。這里的Class需要填入MessageSource接口的實(shí)現(xiàn)六水。其中,在我看的書(shū)中只提及了兩個(gè)類盒延,一個(gè)是:ResourceBundleMessageSource缩擂,另一個(gè)則是ReloadableResourceBundleMessageSource。其中添寺,后者提供了無(wú)需重啟就可重新加載新配置的特性胯盯。
list節(jié)點(diǎn)的value子節(jié)點(diǎn)中的body值“org/rjstudio/spring/properties/messages”,是指org.rjstudio.spring.proerties包下的以messages為主要名稱的properties文件计露。比如說(shuō)博脑,以Locale為zh_CN為例,Spring會(huì)自動(dòng)在類路徑中在org.rjstudio.spring.properties包下按照如下順序搜尋配置文件并進(jìn)行加載票罐。

接下來(lái)叉趣,讓我們?cè)趏rg.rjstudio.spring.properties下,建立兩個(gè)messages的屬性文件该押。一個(gè)名為messages_zh_CN.properties疗杉,另一個(gè)為messages_en_US.properties,分別對(duì)應(yīng)國(guó)際化中的中國(guó)和美國(guó)蚕礼。

在這兩個(gè)屬性文件中分別建立一個(gè)userinfo屬性烟具。 
    中國(guó)為:userinfo=當(dāng)前登陸用戶[{0}] 登陸時(shí)間[{1}] 
    美國(guó)為:userinfo=current login user:[{0}] login time:[{1}] 

好了,一切就緒奠蹬,接下來(lái)可以寫(xiě)段代碼來(lái)測(cè)試了朝聋。。建個(gè)類囤躁,寫(xiě)個(gè)測(cè)試Main方法冀痕。 
public class MessageTest { 
        public static void main(String[] args) { 
            ApplicationContext ctx = new ClassPathXmlApplicationContext("messages.xml"); 
            Object[] arg = new Object[] { "Erica", Calendar.getInstance().getTime() }; 
            String msg = ctx.getMessage("userinfo", arg,Locale.CHINA);  //使用中文資源配置
            System.out.println("Message is ===> " + msg); 
        } 
    } 
    
    //最后輸出的結(jié)果是:Message is ===> 當(dāng)前登錄用戶:[Erica] 登錄時(shí)間:[07-6-8 上午10:20] 

ctx.getMessage("userinfo", arg,Locale.US);
/*這個(gè)方法,傳入的三個(gè)參數(shù)狸演,第一個(gè)是properties文件中對(duì)應(yīng)的名言蛇。arg為一個(gè)對(duì)象數(shù)組,我們?cè)趐roperties里面放置了兩個(gè)變量宵距,[{0}]和[{1}]猜极,Spring會(huì)為我們給它們賦值。而最后則需要傳入一個(gè)Local消玄。這里用 Locale.CHINA代表中國(guó)跟伏。如果我們用Locale.US,則輸出會(huì)變?yōu)椋?
    
    Message is ===> current login user:[Erica] login time:[6/8/07 10:59 AM] 
*/
    
  • NotificationPublisherAware翩瓜,jmx相關(guān)受扳,后續(xù)深究
  • ResourceLoaderAware

資源加載器注入,ApplicationContext也實(shí)現(xiàn)了ResourceLoader.
在Spring里面還定義有一個(gè)ResourceLoader接口兔跌,該接口中只定義了一個(gè)用于獲取Resource的getResource(String location)方法勘高。它的實(shí)現(xiàn)類有很多,這里我們先挑一個(gè)DefaultResourceLoader來(lái)講坟桅。DefaultResourceLoader在獲取Resource時(shí)采用的是這樣的策略:首先判斷指定的location是否含有“classpath:”前綴华望,如果有則把location去掉“classpath:”前綴返回對(duì)應(yīng)的ClassPathResource;否則就把它當(dāng)做一個(gè)URL來(lái)處理仅乓,封裝成一個(gè)UrlResource進(jìn)行返回赖舟;如果當(dāng)成URL處理也失敗的話就把location對(duì)應(yīng)的資源當(dāng)成是一個(gè)ClassPathResource進(jìn)行返回。

@Test  
public void testResourceLoader() {  
   ResourceLoader loader = new DefaultResourceLoader();  
   Resource resource = loader.getResource("http://www.google.com.hk");  
   System.out.println(resource instanceof UrlResource); //true  
   //注意這里前綴不能使用“classpath*:”夸楣,這樣不能真正訪問(wèn)到對(duì)應(yīng)的資源宾抓,exists()返回false  
   resource = loader.getResource("classpath:test.txt");  
   System.out.println(resource instanceof ClassPathResource); //true  
   resource = loader.getResource("test.txt");  
   System.out.println(resource instanceof ClassPathResource); //true  
}

ApplicationContext接口也繼承了ResourceLoader接口,所以它的所有實(shí)現(xiàn)類都實(shí)現(xiàn)了ResourceLoader接口豫喧,都可以用來(lái)獲取Resource石洗。
對(duì)于ClassPathXmlApplicationContext而言,它在獲取Resource時(shí)繼承的是它的父類DefaultResourceLoader的策略紧显。
FileSystemXmlApplicationContext也繼承了DefaultResourceLoader讲衫,但是它重寫(xiě)了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在獲取資源文件時(shí)首先也是判斷指定的location是否包含“classpath:”前綴孵班,如果包含涉兽,則把location中“classpath:”前綴后的資源從類路徑下獲取出來(lái),當(dāng)做一個(gè)ClassPathResource重父;否則花椭,繼續(xù)嘗試把location封裝成一個(gè)URL,返回對(duì)應(yīng)的UrlResource房午;如果還是失敗矿辽,則把location指定位置的資源當(dāng)做一個(gè)FileSystemResource進(jìn)行返回。

  • ServletConfigAware
public interface ServletConfig {
    

    /**
     * Returns the name of this servlet instance.
     * The name may be provided via server administration, assigned in the 
     * web application deployment descriptor, or for an unregistered (and thus
     * unnamed) servlet instance it will be the servlet's class name.
     *
     * @return      the name of the servlet instance
     *
     *
     *
     */

    public String getServletName();

    /**
     * Returns a reference to the {@link ServletContext} in which the caller
     * is executing.
     *
     *
     * @return      a {@link ServletContext} object, used
     *          by the caller to interact with its servlet 
     *                  container
     * 
     * @see     ServletContext
     *
     */

    public ServletContext getServletContext();
    
    /**
     * Returns a <code>String</code> containing the value of the 
     * named initialization parameter, or <code>null</code> if 
     * the parameter does not exist.
     *
     * @param name  a <code>String</code> specifying the name
     *          of the initialization parameter
     *
     * @return      a <code>String</code> containing the value 
     *          of the initialization parameter
     *
     */

    public String getInitParameter(String name);


    /**
     * Returns the names of the servlet's initialization parameters
     * as an <code>Enumeration</code> of <code>String</code> objects, 
     * or an empty <code>Enumeration</code> if the servlet has
     * no initialization parameters.
     *
     * @return      an <code>Enumeration</code> of <code>String</code> 
     *          objects containing the names of the servlet's 
     *          initialization parameters
     *
     *
     *
     */

    public Enumeration getInitParameterNames();


}
  • ServletContextAware,注入ServletContext

【ServletContext的5大作用】
ServletContext,是一個(gè)全局的儲(chǔ)存信息的空間郭厌,服務(wù)器開(kāi)始袋倔,其就存在,服務(wù)器關(guān)閉折柠,其才釋放宾娜。request,一個(gè)用戶可有多個(gè)扇售;session前塔,一個(gè)用戶一個(gè)嚣艇;而servletContext,所有用戶共用一個(gè)华弓。所以食零,為了節(jié)省空間,提高效率寂屏,ServletContext中贰谣,要放必須的、重要的迁霎、所有用戶需要共享的線程又是安全的一些信息吱抚。
1.獲取web的上下文路徑

String getContextPath();

2.獲取全局的參數(shù)

String getInitParameter(String name);

Enumeration getInitParameterNames();

3.和域?qū)ο笙嚓P(guān)的

void setAttribute(String name,Onject object);

Object getAttribute(String name);

void removeAttribute(String name);

域?qū)ο螅ㄓ驅(qū)ο缶褪窃诓煌Y源之前來(lái)共享數(shù)據(jù),保存數(shù)據(jù)考廉,獲取數(shù)據(jù))

ServletContext是我們學(xué)習(xí)的第一個(gè)域?qū)ο?Servlet共有三個(gè)域?qū)ο骃ervletContext秘豹、HttpServletRequest、HttpSession)

  1. 請(qǐng)求轉(zhuǎn)發(fā)的

RequestDispatcher getRequestDispatcher(String path);

在Servlet跳轉(zhuǎn)頁(yè)面:

4.1請(qǐng)求重定向(你找我借錢(qián)芝此,我沒(méi)有憋肖,你自己去找他借錢(qián))

1.地址欄會(huì)改變,變成重定向到的地址

2.可以跳轉(zhuǎn)到項(xiàng)目?jī)?nèi)的資源婚苹,也可以跳轉(zhuǎn)項(xiàng)目外的資源

3.瀏覽器向服務(wù)器發(fā)出兩次請(qǐng)求岸更,那么不能使用請(qǐng)求來(lái)作為域?qū)ο髞?lái)共享數(shù)據(jù)。

4.2請(qǐng)求轉(zhuǎn)發(fā)(你找我借錢(qián)膊升,我沒(méi)有怎炊,我?guī)湍闳ハ蛩桢X(qián))

1.地址欄不會(huì)改變

2.只能跳轉(zhuǎn)到項(xiàng)目?jī)?nèi)的資源,不能跳轉(zhuǎn)項(xiàng)目外的資源廓译。

3.瀏覽器向服務(wù)器發(fā)出一次請(qǐng)求评肆,那么可以使用請(qǐng)求作為域?qū)ο蠊蚕頂?shù)據(jù)。

5.讀取web項(xiàng)目的資源文件

String getRealPath(String path);

InputStream getResourceAsStream(String path);

URL getResource(String path);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末非区,一起剝皮案震驚了整個(gè)濱河市瓜挽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌征绸,老刑警劉巖久橙,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異管怠,居然都是意外死亡淆衷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)渤弛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)祝拯,“玉大人,你說(shuō)我怎么就攤上這事她肯〖淹罚” “怎么了鹰贵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)康嘉。 經(jīng)常有香客問(wèn)我砾莱,道長(zhǎng),這世上最難降的妖魔是什么凄鼻? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮聚假,結(jié)果婚禮上块蚌,老公的妹妹穿的比我還像新娘。我一直安慰自己膘格,他們只是感情好峭范,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瘪贱,像睡著了一般纱控。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菜秦,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天甜害,我揣著相機(jī)與錄音,去河邊找鬼球昨。 笑死尔店,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的主慰。 我是一名探鬼主播嚣州,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼共螺!你這毒婦竟也來(lái)了该肴?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤藐不,失蹤者是張志新(化名)和其女友劉穎匀哄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體佳吞,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拱雏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了底扳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铸抑。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖衷模,靈堂內(nèi)的尸體忽然破棺而出鹊汛,到底是詐尸還是另有隱情蒲赂,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布刁憋,位于F島的核電站滥嘴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏至耻。R本人自食惡果不足惜若皱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尘颓。 院中可真熱鬧走触,春花似錦、人聲如沸疤苹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卧土。三九已至惫皱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尤莺,已是汗流浹背旅敷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缝裁,地道東北人扫皱。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像捷绑,于是被迫代替她去往敵國(guó)和親韩脑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容