2021SC@SDUSC
This blog is a continuation of the previous blog. First, analyze the remaining code in the avalon folder in the spring folder, and then continue to analyze the contents of other folders under the core folder. It includes the logger under the spring folder, avalon under the xml folder, and some other java files under the core folder. Due to a lot of content, I may choose to focus on analysis. I'll just take some classes that are not very focused.
PoolableFactoryBean.java
This factory bean adds simple pool support to Spring.
Some attributes that need attention:
Attribute name | Attribute description |
---|---|
beanClass | class |
beanFactory | Corresponding bean factory |
DEFAULT_MAX_POOL_SIZE | Default maximum size of the pool |
interfaces | All interfaces of the agent |
name | Hybrid component |
semaphore | Object to synchronize access to get and put methods |
Constructor:
Overload, create a PoolableComponentHandler to manage the component pool created by the specified factory object.
public PoolableFactoryBean( String name, String className ) throws Exception { this(name, className, DEFAULT_MAX_POOL_SIZE, null); } public PoolableFactoryBean( String name, String className, String poolMaxString, Settings settings ) throws Exception { String value = poolMaxString; if ( settings != null ) { value = PropertyHelper.replace(poolMaxString, settings); } int poolMax = Integer.valueOf(value).intValue(); this.name = name; this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax ); this.beanClass = Class.forName(className); final HashSet workInterfaces = new HashSet(); //Get all interfaces this.guessWorkInterfaces( this.beanClass, workInterfaces ); //Add AvalonPoolable workInterfaces.add(AvalonPoolable.class); this.interfaces = (Class[]) workInterfaces.toArray( new Class[workInterfaces.size()] ); //Create pool list this.ready = new LinkedList(); }
Other important methods:
1.dispose():
Process associated pools and factories.
public void dispose() { //Any Poolables in the preparation list need to be processed synchronized( this.semaphore ) { //Remove objects from the preparation list for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) { Object poolable = iter.next(); iter.remove(); this.readySize--; this.permanentlyRemovePoolable( poolable ); } } }
2.enteringPool():
Process service specific methods and put them into the pool
protected void enteringPool( final Object component ) { try { //Processing recyclable objects if( component instanceof Recyclable ) { ( (Recyclable)component ).recycle(); } if ( this.poolInMethod != null ) { this.poolInMethod.invoke(component, null); } } catch (Exception ignore) { //During the process of putting the component back into the pool, we ignore the exception because it will not cause the system to crash -- this is for compatibility with the original Avalon implementation this.log.error("Exception while putting component '" + component + "' back into the pool.", ignore); } }
3.exitingPool():
Process service specific methods and remove them from the pool
protected void exitingPool( final Object component ) throws Exception { if ( this.poolOutMethod != null ) { this.poolOutMethod.invoke(component, null); } }
4.getFromPool():
Get a Poolable from the pool.
If there is space in the pool, a new Poolable is created. Depending on the parameters of the constructor, the method may block or throw an exception if Poolable on the pool is not available.
public Object getFromPool() throws Exception { Object poolable; synchronized( this.semaphore ) { //In M_ Find Poolable at the end of the ready list if ( this.readySize > 0 ){ //poolable is ready and waiting in the pool poolable = this.ready.removeLast(); this.readySize--; } else { //Create a new poolable. If the pool cannot be instantiated, an exception may be thrown. poolable = this.beanFactory.getBean(this.name); this.size++; this.highWaterMark = (this.highWaterMark < this.size ? this.size : this.highWaterMark); } } this.exitingPool(poolable); return poolable; }
5.permanentlyRemovePoolable():
Permanently delete a pool from the pool's active list and destroy it so that it will never be reused
This method is only locked m_ Thread call of semaphore.
protected void permanentlyRemovePoolable( Object poolable ) { this.size--; }
6.putIntoPool():
Return pool object to pool
public void putIntoPool( final Object poolable ) { this.enteringPool(poolable); synchronized( this.semaphore ) { if( this.size <= this.max ) { this.ready.addLast( poolable ); this.readySize++; } else { //Create more Poolables than the pool can hold, so please delete. this.permanentlyRemovePoolable( poolable ); } } }
7. Guess workinterfaces() and addInterfaces():
Get the interface list of the agent by scanning all interfaces implemented by a class
private void guessWorkInterfaces( final Class clazz, final Set workInterfaces ) { if ( null != clazz ) { this.addInterfaces( clazz.getInterfaces(), workInterfaces ); this.guessWorkInterfaces( clazz.getSuperclass(), workInterfaces ); } } private void addInterfaces( final Class[] classInterfaces, final Set workInterfaces ) { for ( int i = 0; i < classInterfaces.length; i++ ) { workInterfaces.add( classInterfaces[i] ); this.addInterfaces(classInterfaces[i].getInterfaces(), workInterfaces); } }
SitemapHelper.java
There are two important attributes:
- Default location for spring related child configuration files
- DEFAULT_CHILD_PROPERTIES_LOCATION
- DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION
There are some methods worth analyzing:
1.addHeader():
Add header of xml configuration file
protected static void addHeader(StringBuffer buffer) { buffer.append("<beans xmlns=\"http://www.springframework.org/schema/beans\""); buffer.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""); buffer.append(" xmlns:util=\"http://www.springframework.org/schema/util\""); buffer.append(" xmlns:configurator=\"http://cocoon.apache.org/schema/configurator\""); buffer.append(" xmlns:avalon=\"http://cocoon.apache.org/schema/avalon\""); buffer.append(" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"); buffer.append(" http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"); buffer.append(" http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.xsd"); buffer.append(" http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd\">\n"); }
2.addFooter():
Add footer for xml configuration file
protected static void addFooter(StringBuffer buffer) { buffer.append("</beans>\n"); }
3.addAttribute():
If the xml stream has a value, add an attribute to it
protected static void addAttribute(StringBuffer buffer, String name, String value) { if ( value != null ) { buffer.append(' '); buffer.append(name); buffer.append("=\""); buffer.append(value); buffer.append("\""); } }
4.isUsingDefaultIncludes():
Judge whether to read the site map by default
protected static boolean isUsingDefaultIncludes(Configuration config) { return config.getChild("components").getAttributeAsBoolean("use-default-includes", true); }
5.getBeanIncludes():
Get all the contained information of the bean configuration from the site map
protected static List getBeanIncludes(WebApplicationContext webAppContext, String contextUrl, Configuration sitemap) throws ConfigurationException { final List includes = new ArrayList(); if ( isUsingDefaultIncludes(sitemap) ) { final Resource rsrc = webAppContext.getResource(contextUrl + DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION); if ( rsrc.exists() ) { includes.add(DEFAULT_CHILD_SPRING_CONFIGURATION_LOCATION); } } final Configuration[] includeConfigs = sitemap.getChild("components").getChildren("include-beans"); for(int i = 0 ; i < includeConfigs.length; i++ ) { final String dir = includeConfigs[i].getAttribute("dir"); includes.add(dir); } return includes; }
6.getPropertiesIncludes():
Get all contains of properties from site map
protected static List getPropertiesIncludes(WebApplicationContext webAppContext,String contextUrl,Configuration sitemap) throws ConfigurationException { final List includes = new ArrayList(); if ( isUsingDefaultIncludes(sitemap) ) { final Resource rsrc = webAppContext.getResource(contextUrl + DEFAULT_CHILD_PROPERTIES_LOCATION); if ( rsrc.exists() ) { includes.add(DEFAULT_CHILD_PROPERTIES_LOCATION); } } final Configuration[] includeConfigs = sitemap.getChild("components").getChildren("include-properties"); for(int i = 0 ; i < includeConfigs.length; i++ ) { final String dir = includeConfigs[i].getAttribute("dir"); includes.add(dir); } return includes;java }
7.createContainer():
Create each site map container
public static WebApplicationContext createContainer(Configuration config,String sitemapLocation,Monitor fam,ServletContext servletContext) throws Exception { //Get parent container first final WebApplicationContext parentContext = WebAppContextUtils.getCurrentWebApplicationContext(); final ProcessInfoProvider infoProvider = (ProcessInfoProvider) parentContext.getBean(ProcessInfoProvider.ROLE); final Request request = ObjectModelHelper.getRequest(infoProvider.getObjectModel()); //Determine context url int pos = sitemapLocation.lastIndexOf('/'); if ( sitemapLocation.lastIndexOf(File.separatorChar) > pos ) { pos = sitemapLocation.lastIndexOf(File.separatorChar); } final String contextUrl = sitemapLocation.substring(0, pos + 1); //Get class loader final ClassLoader classloader = Thread.currentThread().getContextClassLoader(); //Create root bean definition final String definition = createDefinition(request.getSitemapURIPrefix(),sitemapLocation.substring(pos+1),getBeanIncludes(parentContext, contextUrl, config),getPropertiesIncludes(parentContext, contextUrl, config),getGlobalSitemapVariables(config)); final ChildXmlWebApplicationContext context = new ChildXmlWebApplicationContext(contextUrl,definition); context.setServletContext(servletContext); context.setParent(parentContext); if ( classloader != null ) { context.setClassLoader(classloader); } context.refresh(); return context; }
Other documents
Name of the class | Class description |
---|---|
PoolableProxyHandler | Agents for all mergeable components |
SettingsContext | This is an extension of the default context implementation. It first looks at the settings object and delegates to the parent object only if the key cannot be found there. This object is used to set up the logger |
ChildLoggerFactoryBean | Spring factory bean to set up a child public logger |
LoggerFactoryBean | The Spring factory bean sets the public logger and the specified class. If no category is set, the default category "cocoon" is used |
LoggerUtils | Commons logger utility |
DefaultDOMParser | Wrapper implementation supporting Excalibur XML interface |
DefaultResolver | Wrapper implementation supporting Excalibur XML interface |
DefaultSAXParser | Wrapper implementation supporting Excalibur XML interface |
WiringNotFoundException | If wiring is not found XML, this exception is thrown |