2015-08-20 71 views
-4

我正在瀏覽反射API,但無法實時應用中實時場景/用例中使用反射創建對象。有沒有人使用反射來創建使用反射和用例的物體?爲什麼我們使用反射創建對象

+0

標籤反射有14652的問題,所以我想有人使用這個API在一些情況下...只是檢查,你沒有標籤的問題。 – SomeJavaGuy

+0

'Object o = clazz.getConstructor()。newInstance()' –

回答

2

這裏有幾個用例:

1)如果你想實現的靈活性,不希望使用依賴注入框架,你可以使用在啓動中定義了應用程序的系統屬性來指定實現類使用。 JAXP使用了很多系統屬性,例如javax.xml.parsers.DocumentBuilderFactory。

例如,如果您有名爲AutoRideService的接口/抽象類,並希望能夠在運行時配置使用的實現,你可以得到這樣的:

private static AutoRideService lookupAutoRideService() { 
    String className = System.getProperty("autorideservice.classname"); 
    try { 
     @SuppressWarnings("unchecked") 
     Class<AutoRideService> clazz = (Class<AutoRideService>) Class.forName(className); 
     return clazz.newInstance(); 
    } catch (Exception ex) { 
     throw new IllegalStateException("Failed to lookup auto ride service using class name: " + className, ex); 
    } 
} 

2)如果您需要使用的在同一個程序中不同的和不兼容的版本。在這裏你可以使用多個類加載器和反射。

例如我有一些Oauth標記存儲在一個數據庫中,它們是由舊版本的Spring Security Oauth2創建的。我想升級Spring Security Oauth2的版本和存儲的標記,但是新版本對反序列化標記所需的類有顯着且向後不兼容的更改。下面是代碼這樣一個片段:

/** 
* This takes serialization data of the old authentication object and then 
* reads it as an object using a separate class loader which has the old version of the spring and spring security classes 
* We then use reflection to access the compatible fields and then use this data to construct the new class version object 
* @param oldAuthData The serialized data created with the old version of the classes 
* @return The deserialized OAuth2Authentication object constructed with the new class versions 
* @throws IOException 
* @throws ClassNotFoundException 
* @throws NoSuchMethodException 
* @throws IllegalAccessException 
* @throws InvocationTargetException 
*/ 
private OAuth2Authentication deserializeOAuth2Authentication(byte[] oldAuthData) throws IOException, ClassNotFoundException, NoSuchMethodException, 
     IllegalAccessException, InvocationTargetException { 
    OAuth2Authentication auth = null; 
    ObjectInputStream ois = new CustomObjectInputStream(new ByteArrayInputStream(oldAuthData), this.deserialisationClassLoader); 
    try { 
     Object obj = ois.readObject(); 

     // the instance of this is the old OAuth2Authentication however we cannot cast 
     // so have to use reflection to access the fields and data 
     // and then construct a new OAuth2Authentication from this 

     Object oldAuthorizationRequest = MethodUtils.invokeMethod(obj, "getAuthorizationRequest", NO_ARGS); 

     Object authentication = MethodUtils.invokeMethod(obj, "getUserAuthentication", NO_ARGS); 
     Object principal = MethodUtils.invokeMethod(authentication, "getPrincipal", NO_ARGS); 
     Object credentials = MethodUtils.invokeMethod(authentication, "getCredentials", NO_ARGS); 
     Collection<GrantedAuthority> authorities = convertAuthorities((Collection<?>) MethodUtils.invokeMethod(authentication, "getAuthorities", NO_ARGS)); 

     // now construct the oauth authentication object with the new auth and request 
     Authentication authToken = new UsernamePasswordAuthenticationToken(principal, credentials, authorities); 
     AuthorizationRequest authReq = convertAuthorizationRequest(oldAuthorizationRequest); 
     auth = new OAuth2Authentication(authReq, authToken); 

    } finally { 
     ois.close(); 
    } 
    return auth; 
} 
相關問題