blob: be52fa87c587ab036605a713f021177bee917ebf [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_281) on Sun Jan 15 15:58:34 CET 2023 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>BeansWrapperBuilder (FreeMarker 2.3.32 API)</title>
<meta name="date" content="2023-01-15">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="BeansWrapperBuilder (FreeMarker 2.3.32 API)";
}
}
catch(err) {
}
//-->
var methods = {"i0":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/BeansWrapperBuilder.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-all.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../freemarker/ext/beans/BeansWrapper.MethodAppearanceDecisionInput.html" title="class in freemarker.ext.beans"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html" title="class in freemarker.ext.beans"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?freemarker/ext/beans/BeansWrapperBuilder.html" target="_top">Frames</a></li>
<li><a href="BeansWrapperBuilder.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">freemarker.ext.beans</div>
<h2 title="Class BeansWrapperBuilder" class="title">Class BeansWrapperBuilder</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li>java.lang.Object</li>
<li>
<ul class="inheritance">
<li><a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html" title="class in freemarker.ext.beans">freemarker.ext.beans.BeansWrapperConfiguration</a></li>
<li>
<ul class="inheritance">
<li>freemarker.ext.beans.BeansWrapperBuilder</li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="description">
<ul class="blockList">
<li class="blockList">
<dl>
<dt>All Implemented Interfaces:</dt>
<dd>java.lang.Cloneable</dd>
</dl>
<hr>
<br>
<pre>public class <span class="typeNameLabel">BeansWrapperBuilder</span>
extends <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html" title="class in freemarker.ext.beans">BeansWrapperConfiguration</a></pre>
<div class="block">Gets/creates a <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> singleton instance that's already configured as specified in the properties of
this object; this is recommended over using the <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> constructors. The returned instance can't be
further configured (it's write protected).
<p>The builder meant to be used as a drop-away object (not stored in a field), like in this example:
<pre>
BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build();
</pre>
<p>Or, a more complex example:</p>
<pre>
// Create the builder:
BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
// Set desired BeansWrapper configuration properties:
builder.setUseModelCache(true);
builder.setExposeFields(true);
// Get the singleton:
BeansWrapper beansWrapper = builder.build();
// You don't need the builder anymore.
</pre>
<p>Despite that builders aren't meant to be used as long-lived objects (singletons), the builder is thread-safe after
you have stopped calling its setters and it was safely published (see JSR 133) to other threads. This can be useful
if you have to put the builder into an IoC container, rather than the singleton it produces.
<p>The main benefit of using a builder instead of a <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> constructor is that this way the
internal object wrapping-related caches (most notably the class introspection cache) will come from a global,
JVM-level (more precisely, <code>freemarker.jar</code>-class-loader-level) cache. Also the <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> singletons
themselves are stored in this global cache. Some of the wrapping-related caches are expensive to build and can take
significant amount of memory. Using builders, components that use FreeMarker will share <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a>
instances and said caches even if they use separate FreeMarker <a href="../../../freemarker/template/Configuration.html" title="class in freemarker.template"><code>Configuration</code></a>-s. (Many Java libraries use
FreeMarker internally, so <a href="../../../freemarker/template/Configuration.html" title="class in freemarker.template"><code>Configuration</code></a> sharing is not an option.)
<p>Note that the returned <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> instances are only weak-referenced from inside the builder mechanism,
so singletons are garbage collected when they go out of usage, just like non-singletons.
<p>About the object wrapping-related caches:
<ul>
<li><p>Class introspection cache: Stores information about classes that once had to be wrapped. The cache is
stored in the static fields of certain FreeMarker classes. Thus, if you have two <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a>
instances, they might share the same class introspection cache. But if you have two
<code>freemarker.jar</code>-s (typically, in two Web Application's <code>WEB-INF/lib</code> directories), those won't
share their caches (as they don't share the same FreeMarker classes).
Also, currently there's a separate cache for each permutation of the property values that influence class
introspection:
<a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setExposeFields-boolean-"><code>expose_fields</code></a>, and
<a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setExposureLevel-int-"><code>exposure_level</code></a>, and
<a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setMemberAccessPolicy-freemarker.ext.beans.MemberAccessPolicy-"><code>BeansWrapperConfiguration.setMemberAccessPolicy(MemberAccessPolicy)</code></a> member_access_policy}.
So only <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> where those properties are the same may share class introspection caches among each
other.
</li>
<li><p>Model caches: These are local to a <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a>. <a href="../../../freemarker/ext/beans/BeansWrapperBuilder.html" title="class in freemarker.ext.beans"><code>BeansWrapperBuilder</code></a> returns the same
<a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> instance for equivalent properties (unless the existing instance was garbage collected
and thus a new one had to be created), hence these caches will be re-used too. <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> instances
are cached in the static fields of FreeMarker too, but there's a separate cache for each
Thread Context Class Loader, which in a servlet container practically means a separate cache for each Web
Application (each servlet context). (This is like so because for resolving class names to classes FreeMarker
uses the Thread Context Class Loader, so the result of the resolution can be different for different
Thread Context Class Loaders.) The model caches are:
<ul>
<li><p>
Static model caches: These are used by the hash returned by <a href="../../../freemarker/ext/beans/BeansWrapper.html#getEnumModels--"><code>BeansWrapper.getEnumModels()</code></a> and
<a href="../../../freemarker/ext/beans/BeansWrapper.html#getStaticModels--"><code>BeansWrapper.getStaticModels()</code></a>, for caching <a href="../../../freemarker/template/TemplateModel.html" title="interface in freemarker.template"><code>TemplateModel</code></a>-s for the static methods/fields
and Java enums that were accessed through them. To use said hashes, you have to put them
explicitly into the data-model or expose them to the template explicitly otherwise, so in most applications
these caches aren't unused.
</li>
<li><p>
Instance model cache: By default off (see <a href="../../../freemarker/ext/beans/BeansWrapper.html#setUseCache-boolean-"><code>BeansWrapper.setUseCache(boolean)</code></a>). Caches the
<a href="../../../freemarker/template/TemplateModel.html" title="interface in freemarker.template"><code>TemplateModel</code></a>-s for all Java objects that were accessed from templates.
</li>
</ul>
</li>
</ul>
<p>Note that what this method documentation says about <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> also applies to
<a href="../../../freemarker/template/DefaultObjectWrapperBuilder.html" title="class in freemarker.template"><code>DefaultObjectWrapperBuilder</code></a>.</div>
<dl>
<dt><span class="simpleTagLabel">Since:</span></dt>
<dd>2.3.21</dd>
</dl>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor.summary">
<!-- -->
</a>
<h3>Constructor Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colOne" scope="col">Constructor and Description</th>
</tr>
<tr class="altColor">
<td class="colOne"><code><span class="memberNameLink"><a href="../../../freemarker/ext/beans/BeansWrapperBuilder.html#BeansWrapperBuilder-freemarker.template.Version-">BeansWrapperBuilder</a></span>(<a href="../../../freemarker/template/Version.html" title="class in freemarker.template">Version</a>&nbsp;incompatibleImprovements)</code>
<div class="block">See <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#BeansWrapperConfiguration-freemarker.template.Version-"><code>BeansWrapperConfiguration.BeansWrapperConfiguration(Version)</code></a>.</div>
</td>
</tr>
</table>
</li>
</ul>
<!-- ========== METHOD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code><a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans">BeansWrapper</a></code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../freemarker/ext/beans/BeansWrapperBuilder.html#build--">build</a></span>()</code>
<div class="block">Returns a <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> instance that matches the settings of this builder.</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a name="methods.inherited.from.class.freemarker.ext.beans.BeansWrapperConfiguration">
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;freemarker.ext.beans.<a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html" title="class in freemarker.ext.beans">BeansWrapperConfiguration</a></h3>
<code><a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#clone-boolean-">clone</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#equals-java.lang.Object-">equals</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getDefaultDateType--">getDefaultDateType</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getExposeFields--">getExposeFields</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getExposureLevel--">getExposureLevel</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getIncompatibleImprovements--">getIncompatibleImprovements</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getMemberAccessPolicy--">getMemberAccessPolicy</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getMethodAppearanceFineTuner--">getMethodAppearanceFineTuner</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getOuterIdentity--">getOuterIdentity</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getPreferIndexedReadMethod--">getPreferIndexedReadMethod</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getTreatDefaultMethodsAsBeanMembers--">getTreatDefaultMethodsAsBeanMembers</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#getUseModelCache--">getUseModelCache</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#hashCode--">hashCode</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#isSimpleMapWrapper--">isSimpleMapWrapper</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#isStrict--">isStrict</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setDefaultDateType-int-">setDefaultDateType</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setExposeFields-boolean-">setExposeFields</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setExposureLevel-int-">setExposureLevel</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setMemberAccessPolicy-freemarker.ext.beans.MemberAccessPolicy-">setMemberAccessPolicy</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setMethodAppearanceFineTuner-freemarker.ext.beans.MethodAppearanceFineTuner-">setMethodAppearanceFineTuner</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setOuterIdentity-freemarker.template.ObjectWrapper-">setOuterIdentity</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setPreferIndexedReadMethod-boolean-">setPreferIndexedReadMethod</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setSimpleMapWrapper-boolean-">setSimpleMapWrapper</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setStrict-boolean-">setStrict</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setTreatDefaultMethodsAsBeanMembers-boolean-">setTreatDefaultMethodsAsBeanMembers</a>, <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#setUseModelCache-boolean-">setUseModelCache</a></code></li>
</ul>
<ul class="blockList">
<li class="blockList"><a name="methods.inherited.from.class.java.lang.Object">
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
<code>clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor.detail">
<!-- -->
</a>
<h3>Constructor Detail</h3>
<a name="BeansWrapperBuilder-freemarker.template.Version-">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>BeansWrapperBuilder</h4>
<pre>public&nbsp;BeansWrapperBuilder(<a href="../../../freemarker/template/Version.html" title="class in freemarker.template">Version</a>&nbsp;incompatibleImprovements)</pre>
<div class="block">See <a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html#BeansWrapperConfiguration-freemarker.template.Version-"><code>BeansWrapperConfiguration.BeansWrapperConfiguration(Version)</code></a>.</div>
</li>
</ul>
</li>
</ul>
<!-- ============ METHOD DETAIL ========== -->
<ul class="blockList">
<li class="blockList"><a name="method.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a name="build--">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>build</h4>
<pre>public&nbsp;<a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans">BeansWrapper</a>&nbsp;build()</pre>
<div class="block">Returns a <a href="../../../freemarker/ext/beans/BeansWrapper.html" title="class in freemarker.ext.beans"><code>BeansWrapper</code></a> instance that matches the settings of this builder. This will be possibly a
singleton that is also in use elsewhere, not necessarily a new object.</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="class-use/BeansWrapperBuilder.html">Use</a></li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../index-all.html">Index</a></li>
<li><a href="../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../freemarker/ext/beans/BeansWrapper.MethodAppearanceDecisionInput.html" title="class in freemarker.ext.beans"><span class="typeNameLink">Prev&nbsp;Class</span></a></li>
<li><a href="../../../freemarker/ext/beans/BeansWrapperConfiguration.html" title="class in freemarker.ext.beans"><span class="typeNameLink">Next&nbsp;Class</span></a></li>
</ul>
<ul class="navList">
<li><a href="../../../index.html?freemarker/ext/beans/BeansWrapperBuilder.html" target="_top">Frames</a></li>
<li><a href="BeansWrapperBuilder.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor.summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor.detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>