⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioc-bean.xtp

📁 RESIN 3.2 最新源码
💻 XTP
📖 第 1 页 / 共 2 页
字号:
<document><header><product>resin</product><title>Bean Configuration (Setter Injection)</title><description><p>Resin configures beans using bean-style (setter injection)patterns, supporting the Inversion-of-Control design pattern.A "bean" is any plain-old Java object which follows standardconfiguration patterns.  Because Resin can find the bean-style settersfrom looking at the class, it can configure those setters in aconfiguration file like the web.xml.</p><p>Resin's configuration follows the <em>Assembly Line</em>or <em>Dependency Injection</em> pattern.</p></description></header><body><localtoc/><s1 title="Overview"><p>The Assembly Line pattern gives configuration responsibility to thecontainer where it belongs, while keeping the application code independentof the container.  Bean-style configuration setters for simple propertiesform the foundation for the Assembly Line pattern.  If an applicationfollows the bean patterns, it can be configuration in any container followingthe Assembly Line (setter injection) pattern.</p><p>We strongly recommend following the Assembly Line pattern throughoutan application, even if your application does not use Resin to configureitself.  Following the Assembly Line pattern makes application codeeasier to understand, maintain, configure and test.</p><figure src="assembler-eg1.gif"/></s1><s1 title="Property Configuration: setXXX"><p>The bean configuration form the foundation of the AssemblyLine pattern.  Since most applications already follow the bean patterns,they get property configuration with no changes.</p><p>Each configuration parameter <var>foo</var> has a corresponding setter method<code>setFoo</code> with a single argument for the value.  Resinlooks at the class using Java's reflection to find the <code>setFoo</code>method.</p>        <example title="Bean-style configuration for a single value setter">&lt;init&gt;  &lt;greeting&gt;Hello, World!&lt;/greeting&gt;  &lt;another-greeting&gt;Hello, Mom!&lt;/another-greeting&gt;&lt;/init&gt;</example><example title="Bean-style java code for a single value setter">public class MyBean {  private String _greeting;  private String _anotherGreeting;  public void setGreeting(String greeting)   {    _greeting = greeting;  }  public void setAnotherGreeting(String anotherGreeting)   {    _anotherGreeting = anotherGreeting;  }}</example><s2 title="Type conversion"><p>A setter can have a parameter that has a type other than<code>String</code>. Resin will perform any type conversionnecessary, so you can use integers and doubles as well as strings.</p><example title="Bean-style configuration for type conversion">&lt;init&gt;  &lt;host&gt;www.gryffindor.com&lt;/host&gt;  &lt;port&gt;80&lt;/port&gt;&lt;/init&gt;</example><example title="Bean-style java code for type conversion">public class MyBean {  private String _host;  private int _port;  public void setHost(String host)   {    _host = host;  }  public void setPort(int port)   {    _port = port;  }}</example></s2><s2 title="Compatibility"><p>Property configuration is very portable.  Any serious configuration systemwill configure bean-style properties.</p></s2></s1><s1 title="Setter Injection: setXXX"><p>Setter injection connects resources following the samebean-style setter pattern.  Where bean properties configure simplevalues like strings and integers, setter injection configuresother resources like databases and application components.</p><p>Resin uses JNDI to store the intermediate resources, e.g. storinga database in java:comp/env/jdbc/test.  The configuration filespecifies the JNDI resource using the JSP expression language andjndi.</p><example title="Configuration for Setter Injection">&lt;init&gt;  &lt;data-source&gt;\${jndi("jdbc/test")}&lt;data-source&gt;&lt;/init&gt;</example><example title="Setter Injection for a DataSource">public class MyBean {  private DataSource _dataSource;  public void setDataSource(DataSource ds)  {    _dataSource = ds;  }}</example><s2 title="Compatibility"><p>Setter injection is portable to containers whichsupport dependency injection.</p></s2></s1><s1 title="Container Properties: addXXX"><p>Resources often act as containers for lists of values and map values.The <code>addXXX</code> pattern adds multiple values for a single property.</p><p>A setter method <code>addFoo</code> allows multiple values to bespecified from the configuration.</p><example title="Bean-style configuration for setting multiple values">&lt;init&gt;  &lt;greeting&gt;Hello, World!&lt;/greeting&gt;  &lt;greeting&gt;Hello, Mom!&lt;/greeting&gt;&lt;/init&gt;</example><example title="Bean-style java code for setting multiple values">public class MyBean {  private LinkedList _greetings = new LinkedList();  public void addGreeting(String greeting)   {    _greetings.add(greeting);  }}</example></s1><s1 title="Validation and Assembly: @PostConstruct"><p>Well-written resources will validate their configuration and mayperform additional assembly tasks.  Resin calls methods marked with the@PostConstruct annotation after all the setter methods have been called.</p><example title="Bean-style @PostConstruct">import javax.annotation.PostConstruct;public class MyBean {  private String _language;  private String _country;  Locale locale;  public void setLanguage(String language)   {    _language = language;  }  public void setCountry(int country)   {    _country = country;  }  @PostConstruct  public void init()  {    locale = new Locale(language, country);  }}</example><s2 title="Validation Exceptions"><p>If an exception is thrown from any of the methods in the bean,Resin will attach a file name and line number that correspond to theconfiguration file.</p><example title="Bean-style exceptions">import java.util.Locale;import javax.annotation.PostConstruct;public class MyBean {  private String _language;  private String _country;  Locale _locale;  public void setLanguage(String language)     throws Exception  {    if (language.length() != 2)      throw new Exception("'language' must be a two-character string");    _language = language;  }  public void setCountry(int country)     throws Exception  {    if (country.length() != 2)      throw new Exception("'country' must be a two-character string");    _country = country;  }  @PostConstruct  public void init()   {    if (_country == null)      throw new Exception("'country' is required");    if (_language == null)      throw new Exception("'language' is required");    _locale = new Locale(language,country);  }}</example><results>500 Servlet ExceptionWEB-INF/web.xml:9: java.lang.Exception: 'country' must be a two-character string</results></s2></s1><s1 title="Nested Beans: createXXX"><p>Beans can be nested, allowing a bean to have setters that haveother sub-beans as the type.</p><example title="Bean-style configuration for sub-beans">&lt;init&gt;  &lt;table&gt;    &lt;name&gt;Foo&lt;/name&gt;    &lt;timestamp-field&gt;tstamp&lt;/timestamp-field&gt;  &lt;/table&gt;  &lt;table name="Bar" timestamp-field="ts"/&gt;&lt;/init&gt;</example><example title="Bean-style java code for sub-beans">import javax.annotation.PostConstruct;import javax.sql.*;// a class to periodically clean old log records from the databasepublic class LogCleaner {  List _logTables = new LinkedList();  // the createXXX method is optional, and allows use something other than  // the default constructor for a sub-bean  public LogTable createTable()  {    return new LogTable();  }  // you could also use setTable(LogTable logTable)  public void addTable(LogTable logTable)  {    _logTables.add(logTable);  }  public class LogTable {    String _name;    String _timestampField;    public void setName(String name)    {      _name = name;    }    public void setTimestampField(String timestampField)    {      _timestampField = timestampField;    }    @PostConstruct    public void init()        throws Exception    {      if (_name == null)        throw new Exception("'name' is required");      if (_timestampField == null)        throw new Exception("'timestamp-field' is required");    }    public void cleanTable(DataSource pool)    {      Connection conn = null;      try {        conn = pool.getConnection();        ...      } catch (SQLException e) {        throw new ServletException(e);      } finally {        try {          if (conn != null)            conn.close();        } catch (SQLException e) {        }      }    }  }  ... }</example></s1><s1 title="Setting with the body text"><p>The <code>addText()</code> method will capture the body of the tagfor a bean setter.</p><example title="Bean-style configuration for setting with the body text">&lt;init&gt;  &lt;message&gt;This is the message&lt;/message&gt;&lt;/init&gt;</example><example title="Bean-style java code for setting with the body text">public class MyBean {  Message _msg;  public Message createMessage() { return new Message(); }  public void setMessage(Message msg) { _msg = msg; }  public class Message {    String _text;    public void addText(String text) { _text = text; }    public String getText() { return _text; }  }}</example></s1><s1 title="Returning a different object"><p>There are some unusual cases where the configured bean is just aconfiguration object and you want to return a different bean.  Thebean can implement a method <code>Object replaceObject()</code> to return adifferent object. Called after the @PostConstruct. </p></s1><s1 title="resin:type"><s2 title="resin:type" type="defun"><p>This special attribute can be used with all sub-beans toinstantiate a different bean class than the one defined in the parentbean.</p><p>If a sub-bean is returned from method like <code>SubBeancreateSubBean()</code> then <var>resin:type</var> cannot be used.  A<code>void setParent(Object obj)</code> method in the sub-bean, whichis called before the other setters, provides an opportunity for thesub-bean instance to know it's enclosing object.</p><p>The <var>resin:</var> in <code>resin:type</code> is a namespace prefix automaticallymapped to <var>http://caucho.com/ns/resin</var>. You could use another namespaceprefix, for example if you defined<var>xmlns:foo="http://caucho.com/ns/resin"</var>, you could use <code>foo:type</code>.</p><example title="Bean-style configuration for using resin:type">&lt;resource jndi-name="env/message"&gt;  &lt;type&gt;example.MessageBean&lt;/type&gt;  &lt;init&gt;    &lt;message&gt;This is message 1&lt;/message&gt;    &lt;message&gt;This is message 2&lt;/message&gt;    &lt;message resin:type="example.CustomMessage"&gt;This is message 3&lt;/message&gt;  &lt;/init&gt;&lt;/resource&gt;</example><example title="MessageBean.java">

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -