用 java.lang.reflect.Proxy 简化加锁代码,用 ReadWriteLock 以提高并行性
有一个 CoreManager 接口,用来代表一个服务,每个方法对应服务的一个子功能。
方法 startup() 要求服务在 stoped 状态。
方法 shutdown() 要求服务在 started 状态。
方法 isStarted() 要求服务在 stoped/started 状态。
其它方法,要求服务在 started 状态。
/**
*Allmehtodwillthrow{@link ManageException}thenTargetserverstoped.
*
*/
publicinterface CoreManager {
// ------- Target Server Control ---------------------------
/**
*ShutdownTargetServerCore.
*
*@throwsManageExceptionstartuperror
*/
publicvoid startup() throws ManageException;
/**
*ShutdownTargetServerCore.
*
*@throwsManageExceptionshutdownerror
*/
publicvoid shutdown() throws ManageException;
/**
*returntureifTargetServerisstarted
*@returntheresult
*
*/
publicboolean isStarted();
/**
*Reconfigurethelogsetting
*
*@paramlogConfig
*@throwsManageException
*/
publicvoid configureLog(LogConfig logConfig) throws ManageException;
// ------- Component Manage-------------------------------
/**
*Addcomponent.
*
*@paramcomponentInfo
*@throwsManageExceptionaddfail.
*/
publicvoid addComponent(AbstractComponentBean componentInfo)
throws ManageException;
/**
*Returnallcomponentnames.
*
*@returnnotnull
*@throwsManageException
*/
public String[] getAllComponentNames() throws ManageException;
/**
*Returnthecomponentsetting.
*
*@paramcomponentName
*@returnresultnotnull
*@throwsManageExceptioncomponentnotfound
*/
public AbstractComponentBean getComponentInfo(String componentName)
throws ManageException;
/**
*Removecomponent.
*
*@paramcomponentName
*@throwsManageExceptioncomponentnotfound
*/
publicvoid removeComponent(String componentName) throws ManageException;
/**
*Applynewroutinggraph
*
*@deprecateduse{@link #setNewRouting(ComponentConnector[])}instead
*@paramroutingBeans
*@returntureonlyifallconnectorisseted
*@throwsManageException
*/
@Deprecated
publicboolean
/**
*Applynewroutinggraph
*
*@paramroutingBeans
*@returntureonlyifallconnectorisseted
*@throwsManageException
*/
publicboolean setNewRouting(ComponentConnector[] routingBeans) throws ManageException;
/**
*Changecomponentsetting
*
*@paramcomponentBean
*@throwsManageExceptioncomponentnotfound
*/
publicvoid changeComponentSetting(AbstractComponentBean componentBean)
throws ManageException;
/**
*Returntrueifcomponentexsit.
*
*@paramcomponentName
*@returntheresult
*@throwsManageException
*/
publicboolean isComponentExist(String componentName) throws ManageException;
/**
*Getthedevicecomponentstatus.
*Ifthecomponentin<code>componentNames</code>notexist,UNKNOWNwillreturn.
*
*@paramcomponentNames
*@returnresult
*@throwsManageException
*/
public ConnectionStatus[] getDeviceComponentStatus(String[] componentNames) throws ManageException;
/**
*Settheenabledpropertyofcomponent.
*
*@paramcomponentName
*@paramenabled
*@throwsManageExceptioncomponentnotfound.
*/
publicvoid setComponentEnabledProperty(String componentName,
boolean enabled) throws ManageException;
// ------- Reader Control ----------------------------------
publicvoid setAutoModeOn(String deviceName) throws ManageException;
publicvoid setAutoModeOff(String deviceName) throws ManageException;
public String getVersionNumber(String readerName) throws ManageException;
publiclong getNumberOfReads(String readerName) throws ManageException;
publiclong[] getNumberOfReads(String[] readerNames) throws ManageException;
public Collection<DRFITag> readTags(String readerName)
throws ManageException;
public Collection<DRFITag> readTags(String readerName, int antennaSequenceNo)
throws ManageException;
public Collection<DRFITag> readTags(String readerName,
int[] antennaSequenceNo) throws ManageException;
publicvoid writeTag(String deviceName, String writeFlag, String epc,
String userData, String killCode, int antennaSequenceNo)
throws ManageException;
publicvoid killTag(String deviceName, String uri, String killCode,
int antennaSequence) throws ManageException;
publicvoid setReadPower(String deviceName, int powerPercent)
throws ManageException;
/**
*Sendacommand(Event)toacomponent
*
*@paramtargetCompName
*@paramevent
*@returnmaynull
*@throwsManageExceptionComponentnotfound/stoped.
*/
public Object sendEvent2Component(String targetCompName, Object event)
throws ManageException;
/**
*Sendacommand(Event)toacomponent
*
*@paramtargetCompName
*@paramsrcCompInfo
*@paramevent
*@returnmaynull
*@throwsManageExceptionComponentnotfound/stoped.
*/
public Object sendComponentEvent2Component(String targetCompName,
ConnectorEndpoint srcCompInfo, Object event)
throws ManageException;
public List<ComponentConnector> getAllConnectors() throws ManageException;
publicvoid addConnector(ComponentConnector connector) throws ManageException;
publicvoid removeConnector(ComponentConnector connector) throws ManageException;
}
|
有这样一个最核心的实现:
publicclass ManagerImpl implements CoreManager {
privatefinal TargetServerCore TargetServer;
privatestaticfinal Log log = LogFactory.getLog( ManagerImpl.class );
public ManagerImpl(TargetServerCore TargetServer) {
this.TargetServer = TargetServer;
}
// ------- Target Server Control ---------------------------
/**
*StartTargetServer.
*
*@throwsManageException
* startuperror
*/
publicvoid startup() throws ManageException {
try {
TargetServer.startup();
} catch ( CommonException e ) {
thrownew ManageException( e.getMessage() );
}
}
/**
*ShutdownTargetServer.
*
*@throwsManageException
* shutdownerror
*/
publicvoid shutdown() throws ManageException {
try {
TargetServer.shutdown();
} catch ( CommonException e ) {
thrownew ManageException( e.getMessage() );
}
}
publicboolean isStarted() {
returnTargetServer.isStarted();
}
/**
*Reconfigurethelogsetting
*
*@paramlogConfig
*/
publicvoid configureLog(LogConfig logConfig) {
log.info( "Try to reconfigure log setting" );
File TargetHome = TargetServer.getHelper().getTargetHome();
ConfigureHelper.configLog4jByLogConfigBean( logConfig, TargetHome );
}
// ------- Component Manage-------------------------------
/**
*Addcomponent.
*
*@paramcomponentInfo
*@throwsManageException
* addfail.
*/
publicvoid addComponent(AbstractComponentBean componentInfo)
throws ManageException {
try {
Component c = TargetServer.getHelper().getComponentFactory().createComponent( componentInfo );
TargetServer.getHelper().getComponentMan().addComponent( c );
} catch ( ComponentManException e ) {
log.warn( "Add component failed:" + e.getMessage() );
thrownew ManageException( e.getMessage() );
}
}
/**
*Returnallcomponentnames.
*
*@returnnotnull
*/
public String[] getAllComponentNames() {
returnTargetServer.getHelper().getComponentMan().getAllComponentNames();
}
/**
*Returnthecomponentsetting.
*
*@paramcomponentName
*@returnresultnotnull
*@throwsManageException
* componentnotfound
*/
public AbstractComponentBean getComponentInfo(String componentName)
throws ManageException {
Component component = TargetServer.getHelper().getComponentMan().getComponent( componentName );
if ( component != null ) {
return component.getSettingCopy();
}
thrownew ManageException( "Component not found" );
}
/**
*Removecomponent.
*
*@paramcomponentName
*@throwsManageException
* componentnotfound
*/
publicvoid removeComponent(String componentName) throws ManageException {
Component component = TargetServer.getHelper().getComponentMan().removeComponent( componentName );
if ( component == null ) {
log.warn( "Remove component:" + componentName
+ " failed. component not exist." );
thrownew ManageException( "Component not found" );
}
}
/**
*Applynewroutinggraph
*
*@deprecateduse{@link #setNewRouting(ComponentConnector[])}instead
*@paramroutingBeans
*@returntureonlyifallconnectorisseted
*/
@Deprecated
publicboolean
returnTargetServer.getHelper().getComponentMan().setNewRouting( Arrays
.asList( ComponentConnector
.connectorBeans2ComponentConnectors( routingBeans ) ) );
}
/**
*Applynewroutinggraph
*
*@paramroutingBeans
*@returntureonlyifallconnectorisseted
*/
publicboolean setNewRouting(ComponentConnector[] routingBeans) {
returnTargetServer.getHelper().getComponentMan().setNewRouting( Arrays.asList( routingBeans ) );
}
/**
*Changecomponentsetting
*
*@paramcomponentBean
*@throwsManageException
* componentnotfound
*/
publicvoid changeComponentSetting(AbstractComponentBean componentBean)
throws ManageException {
try {
TargetServer.getHelper().getComponentMan().changeComponentSetting( componentBean );
} catch ( ComponentManException e ) {
log.warn( "Change component setting to:" + componentBean
+ " , failed." );
thrownew ManageException( e.getMessage() );
}
}
/**
*Returntrueifcomponentexsit.
*
*@paramcomponentName
*@returntheresult
*/
publicboolean isComponentExist(String componentName) {
Component component = TargetServer.getHelper().getComponentMan().getComponent( componentName );
if ( component == null ) {
returnfalse;
}
returntrue;
}
/**
*Getthedevicecomponentstatus.Ifthecomponentin
*<code>componentNames</code>notexist,UNKNOWNwillreturn.
*
*@paramcomponentNames
*@returnresult
*/
public ConnectionStatus[] getDeviceComponentStatus(String[] componentNames) {
ConnectionStatus[] result = new ConnectionStatus[componentNames.length];
int i = 0;
for (String componentName : componentNames) {
ConnectionStatus status = ConnectionStatus.UNKNOWN;
Component component = TargetServer.getHelper().getComponentMan().getComponent( componentName );
if ( component != null ) {
try {
DeviceComponent deviceComponent = (DeviceComponent) component;
if ( deviceComponent.isConnected() ) {
status = ConnectionStatus.CONNECTED;
} else {
status = ConnectionStatus.DISCONNECTED;
}
} catch ( ClassCastException e ) {
// do nothing
}
}
result[i] = status;
i++;
}
return result;
}
/**
*Settheenabledpropertyofcomponent.
*
*@paramcomponentName
*@paramenabled
*@throwsManageException
* componentnotfound.
*/
publicvoid setComponentEnabledProperty(String componentName,
boolean enabled) throws ManageException {
Component component = TargetServer.getHelper().getComponentMan().getComponent( componentName );
if ( component == null ) {
thrownew ManageException( "Component not found" );
}
try {
if ( enabled ) {
component.startup();
TargetServer.getHelper().getComponentMan().resetComponentListener( componentName );
} else {
component.shutdown();
}
} catch ( ComponentStateException e ) {
thrownew ManageException(
"Catch a component state exception in changing component state:"
+ e.getMessage() );
}
}
// ------- Reader Control ----------------------------------
publicvoid setAutoModeOn(String deviceName) throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( deviceName );
try {
readerComponent.setAutoModeOn();
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
publicvoid setAutoModeOff(String deviceName) throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( deviceName );
try {
readerComponent.setAutoModeOff();
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
public String getVersionNumber(String readerName) throws ManageException {
// DRFIReaderComponent readerComponent = tryGetReaderComponent(
// readerName );
return"TODO";// TODO
// return readerComponent.( );
}
publiclong getNumberOfReads(String readerName) throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( readerName );
return readerComponent.getNumberOfReads();
}
publiclong[] getNumberOfReads(String[] readerNames) throws ManageException {
long[] result = newlong[readerNames.length];
int i = 0;
for (String readerName : readerNames) {
DRFIReaderComponent readerComponent = tryGetReaderComponent( readerName );
result[i] = readerComponent.getNumberOfReads();
i++;
}
return result;
}
public Collection<DRFITag> readTags(String readerName)
throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( readerName );
try {
return readerComponent.readTags();
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
public Collection<DRFITag> readTags(String readerName, int antennaSequenceNo)
throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( readerName );
try {
return readerComponent.readTags( antennaSequenceNo );
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
public Collection<DRFITag> readTags(String readerName,
int[] antennaSequenceNo) throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( readerName );
try {
return readerComponent.readTags( antennaSequenceNo );
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
publicvoid writeTag(String deviceName, String writeFlag, String epc,
String userData, String killCode, int antennaSequenceNo)
throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( deviceName );
try {
readerComponent.writeTag( writeFlag, epc, userData, killCode,
antennaSequenceNo );
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
publicvoid killTag(String deviceName, String uri, String killCode,
int antennaSequence) throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( deviceName );
try {
readerComponent.killTag( uri, killCode, antennaSequence );
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
publicvoid setReadPower(String deviceName, int powerPercent)
throws ManageException {
DRFIReaderComponent readerComponent = tryGetReaderComponent( deviceName );
try {
readerComponent.setReadPower( powerPercent );
} catch ( ComponentImplException e ) {
thrownew ManageException( e.getMessage() );
}
}
private DRFIReaderComponent tryGetReaderComponent(String componentName)
throws ManageException {
Component component = TargetServer.getHelper().getComponentMan().getComponent( componentName );
if ( component == null ) {
thrownew ManageException( "Componet not found" );
}
try {
DRFIReaderComponent readerComponent = (DRFIReaderComponent) component;
return readerComponent;
} catch ( ClassCastException e ) {
thrownew ManageException( "Componet is not a DRFIReader" );
}
}
public Object sendEvent2Component(String targetCompName, Object event)
throws ManageException {
try {
return sendComponentEvent2Component( targetCompName, new ConnectorEndpoint( "", 0 ) ,event );
} catch ( ManageException e1 ) {
thrownew ManageException( e1.getMessage(), e1 );
}
}
public Object sendComponentEvent2Component(String targetCompName,
ConnectorEndpoint srcCompInfo, Object event) throws ManageException {
Component component = TargetServer.getHelper().getComponentMan().getComponent( targetCompName );
if ( component == null ) {
thrownew ManageException( "Componet not found" );
}
try {
ComponentEvent<Object> compEvent = new ComponentEvent<Object>( srcCompInfo.getComponentName(), System
.currentTimeMillis(), srcCompInfo.getComponentPort(), Arrays.asList( event ) );
return component.onEvent( compEvent );
} catch ( ComponentStateException e1 ) {
thrownew ManageException( "Component is stoped" );
}
}
public List<ComponentConnector> getAllConnectors() {
returnnew ArrayList<ComponentConnector>( TargetServer.getHelper().getComponentMan().getAllConnectors() );
}
publicvoid addConnector(ComponentConnector connector) {
TargetServer.getHelper().getComponentMan().addConnector( connector );
}
publicvoid removeConnector(ComponentConnector connector) {
TargetServer.getHelper().getComponentMan().removeConnector( connector );
}
}
|
现在有两个要求:
1. 在每个方法调用前检查方法调用的状态要求是否已经达到。
2. 状态加锁
publicclass LockedManagerFactory {
publicstatic CoreManager decorate( CoreManager man, Lock lock ) {
MyInvocationHandler handler = new MyInvocationHandler( man, lock );
Object result = Proxy.newProxyInstance( LockedManagerFactory.class
.getClassLoader(), new Class[] { CoreManager.class }, handler );
return (CoreManager) result;
}
}
publicclass MyInvocationHandler implements InvocationHandler {
private CoreManager impl;
private Lock lock;
private ArrayList<Method> notLockMethods;
private ArrayList<Method> noStartedNeedMethods;
public MyInvocationHandler(CoreManager impl, Lock lock) {
this.impl = impl;
notLockMethods = new ArrayList<Method>();
try {
notLockMethods.add( CoreManager.class.getMethod( "startup", new Class[0] ) );
notLockMethods.add( CoreManager.class.getMethod( "shutdown", new Class[0] ) );
} catch ( Exception e ) {
thrownew RuntimeException( e );
}
noStartedNeedMethods = new ArrayList<Method>();
try {
noStartedNeedMethods.add( CoreManager.class.getMethod( "isStarted", new Class[0] ) );
noStartedNeedMethods.add( CoreManager.class.getMethod( "startup", new Class[0] ) );
noStartedNeedMethods.add( CoreManager.class.getMethod( "shutdown", new Class[0] ) );
} catch ( Exception e ) {
thrownew RuntimeException( e );
}
this.lock = lock;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable{
if( !noStartedNeedMethods.contains( method ) ) {//Target Server started needed
lock.lock();
try {
if( impl.isStarted() == false ) {//TargetServer stoped
thrownew ManageException("TargetServer Stoped");
}
return invoke(method , args );
}finally {
lock.unlock();
}
}
// Target Server started not needed
if( notLockMethods.contains( method ) ) {
return invoke(method , args );
}
else {
lock.lock();
try {
return invoke(method, args );
}finally {
lock.unlock();
}
}
}
private Object invoke(Method method, Object[] args) throws Throwable {
Object returnedResult = null;
try {
returnedResult = method.invoke( impl, args );
} catch ( InvocationTargetException e ) {
throw e.getCause();
} catch( Throwable e ) {
throw e;
}
returnreturnedResult;
}
}
|
现在,客户代码将会是:
/**
*TheTargetserverobject
*
*/
publicclass TargetServerCore {
privatestaticfinal Log log = LogFactory.getLog( TargetServerCore.class );
privatebooleanstarted;
private TargetServerCoreHelper helper;
private Collection<TargetServerLifeCycleListener> listeners;
private Lock readLock;
private Lock writeLock;
private CoreManager manager;
public TargetServerCore() {
started = false;
listeners = new ArrayList<TargetServerLifeCycleListener>();
ReadWriteLock rwLock = new ReentrantReadWriteLock();
readLock = rwLock.readLock();
writeLock = rwLock.writeLock();
manager = new ManagerImpl( this );
manager = LockedManagerFactory.decorate( manager, readLock );
manager = InvokeLogProxyFactory.decorate( manager, Level.DEBUG, Logger.getLogger( TargetServerCore.class ) );
}
public CoreManager getManager() {
returnmanager;
}
public TargetServerCoreHelper getHelper() {
returnhelper;
}
publicfinalboolean isStarted() {
returnstarted;
}
/**
*Returnwhensucessfulstaruped.
*
*@throwsCommonException
* errorappear.
*/
publicvoid startup() throws CommonException {
writeLock.lock();
try {
doStartup( true );
} finally {
writeLock.unlock();
}
}
/**
*Returnwhensuccessfulshutdowned.
*
*@throwsCommonException
* errorappear.
*/
publicvoid shutdown() throws CommonException {
writeLock.lock();
try {
doShutdown();
} finally {
writeLock.unlock();
}
}
/**
*addListener.
*
*@paramlistener
*/
publicvoid addListener(TargetServerLifeCycleListener listener) {
synchronized (listeners) {
this.listeners.add( listener );
}
}
/**
*removeListener.
*
*@paramlistener
*/
publicvoid removeListener(TargetServerLifeCycleListener listener) {
synchronized (listeners) {
this.listeners.remove( listener );
}
}
privatevoid doStartup(boolean reconfigLog) throws CommonException {
if ( started ) {
thrownew CommonException(
"Target Server already startuped, can't startup twice" );
}
helper = new TargetServerCoreHelper( this );
helper.locateFile();
// Configure log by default log setting
if ( reconfigLog ) {
File configFile = new File( helper.TargetConfigHome,
"Target_default_log4j_setting.xml" );
log.info( "Configuring log4j by default configure file:"
+ configFile );
ConfigureHelper.configLog4jByFile( configFile, helper.TargetHome );
}
helper.loadProperties();
helper.loadConfig();
if ( reconfigLog ) {
// Configure log by CustomizeLog4jSettingFile or TargetServer config
helper.reconfigLog4J();
}
helper.updatePlugin();
helper.buildPluginManager();
helper.buildComponentRelated();
helper.initSavedComponents();
started = true;
helper.startupVMHolder();
}
privatevoid doShutdown() throws CommonException {
if ( started == false ) {
thrownew CommonException(
"Target Server haven't startup, can't be shutdown" );
}
// shutdown Component Manager
helper.componentMan.shutdownAllComponent();
started = false;
helper.serverVMHolder.notifyEnd();
helper = null;
notifyAllListenerStateChanged( TargetServerState.STOPED, "" );
}
void notifyAllListenerStateChanged(TargetServerState state, String step) {
synchronized (listeners) {
for( TargetServerLifeCycleListener listener : listeners ) {
listener.stateChanged( state, step );
}
}
}
}
|