📄 resin-ioc.xtp
字号:
<document><header><title>Resin IoC</title><description><p>Resin is designed around an internal inversion-of-control frameworkused for all configuration and resources including servlets, EJBs, messaging,remoting, and databases. Applications can take advantage of Resin'sIoC capabilities using WebBeans-standard annotations and interfaces.</p><p>Since Resin-IoC is used for servlets, WebBeans and EJBs, any applicationbean can use EJB annotations like @TransactionAttribute or WebBeans@InterceptionTypes or event @Observes capabilities, in addition to thedependency injection and IoC configuration.</p><p>The dependency injection framework is type-safe, meaning the registryis organized around Java types, not a flat namespace, which gives morepower and flexibility for component assembly.Since injection is annotation-based, most components can avoid XMLconfiguration, while XML is still available for components.</p></description></header><body><localtoc/><s1 title="See Also"><ul><li>The <a href="resin-ejb.xtp">Resin EJB</a> page gives more informationabout the EJB bean lifecycles and their integration with Resin IoC.</li><li>The <a href="resin-messaging.xtp">Resin messaging</a> page givesmore information about the message bean and its integration with Resin IoC.</li><li>The <a href="resin-remoting.xtp">Resin remoting</a> page showsResin's remoting integration.</li><li>All <a href="config.xtp">Resin configuration</a>, includingall JavaEE specified files uses Resin-IoC as the configuration engine.</li></ul></s1><s1 title="Overview"><p>Resin's IoC support is integrated with <a href="resin-ejb.xtp">EJB 3.0</a> and the core components like Servlets, Filters and remote objects.This integration means plain Java beans can use EJB annotationsand interception, EJBs can use Resin IoC annotations, and both kinds ofbeans can be configured directly from the <code>resin-web.xml</code>or discovered by classpath scanning.</p><p>So it's best to think of Resin-IoC as a set of orthogonal capabilities thatare available to any registered bean. The basic capability types are:</p><ul><li><b>Lifecycle model:</b> Java, <code>@Stateless</code>, <code>@Stateful</code>,or <code>@MessageDriven</code>.Resin-managed objects like Servlets and Filters are Java model beans.</li><li><b>Dependency injection:</b> injection annotations <code>@In</code>, <code>@Named</code>, <code>@EJB</code>, <code>@PersistenceUnit</code>, etc areavailable to all beans.</li><li><b>Registration:</b> all beans are registered in a unified typed-namespaceregistry (i.e. the registration half of dependency injection.)</li><li><b>Lifecycle events:</b> the <code>@PostConstruct</code> and <code>@PreDestroy</code></li><li><b>Predefined aspects:</b> the <code>@TransactionAttribute</code>, <code>@RunAs</code>, <code>@RolesAllowed</code>, etc. annotations areavailable to all beans.</li><li><b>Custom interceptors:</b> EJB-style <code>@AroundInvoke</code>, and <code>@Interceptors</code>, as wellas WebBeans-style <code>@Interceptor</code> and <code>@InterceptorBindingType</code> are available to all beans.</li><li><b>Event handling:</b> the WebBeans <code>@Observes</code> capability is available to all beans.</li></ul></s1><s1 title="Injecting Resources"><p>Before dependency injection, applications needed to use JNDI tograb resources managed by Resin: database connections, JMS queues, JCA<code>EntityManagers</code>, timers, <code>UserTransaction</code>, theJMX <code>MBeanServer</code>, etc. The JNDI lookup had two mainflaws: it required a good chunk of boilerplate code to solve a simpleproblem, and it was untyped. Since JNDI is essentially a big HashMap,the only way of making sure your <code>DataSource</code> name didn'tconflict with your JMS <code>Queue</code> was strictly structuring theJNDI names with patterns like <code>java:comp/env/jdbc/foo</code>.</p><p>With dependency injection, Resin will lookup, verify and injectthe resource when it creates your managed class, for example when creatinga servlet. In the following example, when Resin creates MyServlet, the <code>@In</code> annotation tells it to look for a <code>UserTransaction</code>and <code>DataSource</code> and use reflection to set the fields,before calling the servlet's <code>init()</code> method.</p><example title="Example: DataSource and UserTransaction">import javax.sql.DataSource;import javax.transaction.UserTransaction;import javax.webbeans.In;public class MyServlet extends GenericServlet { @In private DataSource _ds; @In private UserTransaction _ut; ...}</example><s2 title="@Named and bindings"><p>Since many applications use multiple resources like named databases,your injection may need to specify a name or other binding to uniquelyidentify the resource you want. In the case of a unique resource like<code>UserTransaction</code> or <code>MBeanServer</code> or an applicationwith a single <code>DataSource</code>, the <code>@In</code> is enoughinformation. When you have multiple databases, you'll want touse <code>@Named</code> to specify the database name.</p><example title="Example: @Named with DataSource">import javax.sql.DataSource;import javax.webbeans.Named;public class MyServlet extends GenericServlet { @Named("foo") private DataSource _ds; ...}</example><example title="Example: resin-web.xml database configuration"><web-app xmlns="http://caucho.com/ns/resin"> <database> <name>foo</name> <driver type="org.gjt.mm.mysql.Driver"> <url>jdbc:mysql://localhost:3306/foo</url> </driver> </database> <database> <name>bar</name> <driver type="org.gjt.mm.mysql.Driver"> <url>jdbc:mysql://localhost:3306/bar</url> </driver> </database></web-app></example><p>Injection using a <code>@Named</code> binding annotation is stilltyped. You can have a database with <code>@Named("foo")</code> anda JMS queue with <code>@Named("foo")</code>, i.e. each type has its ownnamespace. The typed injection is a big improvement from the JNDI<code>java:comp/env/jdbc/foo</code> vs <code>java:comp/env/jms/foo</code>conventions.</p><p>Although many applications will just use <code>@In</code>and <code>@Named</code>, you can also create yourown <code>BindingType</code> annotations to match resourcesand components.</p></s2><s2 title="field, method, and constructor injection"><p>Since Resin implements all three flavors of dependency injection: field,method and constructor, the choice of style is up to you.</p><p>You can mark any field with <code>@In</code>, <code>@New</code>,<code>@Named</code> or any other <code>@BindingType</code> to tell Resinto inject the field. When a <code>@BindingType</code> is used, Resin willonly match components configured with that binding type.</p><example title="Example: field injection with @Named">import javax.webbeans.Named;public class MyBean { @Named DataSource _ds; ...}</example><p>Method injection can use any binding annotation on any of the parameters.When Resin introspects the component class and it findsany <code>@BindingType</code> or <code>@In</code> parameter on a method, itwill schedule that method to be injected. Method parameters canalso use <code>@New</code>. The method does not need to follow bean-stylesetting conventions; any method will work.</p><example title="Example: method injection with @Named">import javax.webbeans.Named;public class MyBean { void foo(@Named("jdbc/foo") DataSource myDataSource) { ... } ...}</example><p>Construction injection is available for components and singleton beans.Like method injection, the <code>@BindingType</code> valueslike <code>@Named</code> assigned to the parameters determine thevalues to be injected.</p><p>If the bean has multiple constructors, exactly one must be marked<code>@In</code> or have a <code>@BindingType</code> value.</p><example title="Example: constructor injection">import javax.webbeans.In;public class MyBean { @In public MyBean(DataSource myDataSource) { ... } ...}</example></s2><s2 title="WebBeans-enabled components (injectable objects)"><p>Any Resin-managed object can use the entire WebBeansdependency-injection system and all of the managed objects, while objectsyou create using <code>new</code> are still plain Java objects.Once you've got a root object managed by the system, any futherWebBeans components or singletons you bring in will also be managed.The starting set of managed objects is pretty broad and includes:</p><ul><li><bean> (singletons) defined in the resin.xml or resin-web.xml</li><li><component> (WebBeans components) defined in the resin.xml,resin-web.xml or web-beans.xml</li><li>EJB message-driven beans</li><li>EJB session beans</li><li>Filters (servlet)</li><li>JSF resources (currently only model beans)</li><li>JSP pages</li><li>JSP tag libraries</li><li><resource> components (Resin will be migrating to use <bean> for resources in the future.)</li><li>Servlets</li><li>Servlet Listeners defined in the web.xml</li><li>WebBeans annotated components (<code>@Component</code>)discovered through the classpath scan (see below)</li><li>WebBeans components injected with <code>@New</code> (see below)</li><li>Remote services defined by <servlet> (e.g. Hessian or SOAP).</li></ul></s2><s2 title="Resin global resources"><p>Resin automatically provides several global resources to anyinjectable code. Since these resources are unique, your applicationwill use <code>@In</code> as the annotation.</p><p><b><code>javax.webbeans.Container</code></b> provides a reference tothe WebBeans container itself. Applications can use the<code>Container</code> to raise <code>WebBeans</code> events, andlookup components programmatically.</p><p><b><code>javax.webbeans.Conversation</code></b> injects the WebBeansconversation scope for a JSF application. The conversatio scope letsJSF views store data local to the page itself, separate from theHTTP session scope.</p><p><b><code>javax.management.MBeanServer</code></b> injects the JMXmanagement server. JMX manages Resin's resources, so an applicationcan use JMX to view the current state of Resin. See the<a href="http://caucho.com/resin-javadoc/com/caucho/management/server/package-summary.html">JavaDoc</a> for an overview of Resin's resources.</p><p><b><code>javax.transaction.TransactionManager</code></b> injects theXA transaction manager. Advanced applications which want to add theirown <code>XAResource</code> or <code>Synchronization</code> objectsto an active transaction can use <code>@In TransactionManager</code>.</p><p><b><code>javax.transaction.UserTransaction</code></b> injects theXA user transaction manager. Applications controlling XA transactionsprogrammatically will use the <code>UserTransaction</code>to <code>begin()</code>, <code>rollback()</code>, and<code>commit()</code> distributed transactions.</p><p><b><code>java.util.concurrent.ScheduledExecutorService</code></b>lets applications schedule threads and timed events controlled byResin's thread pool, and restricted by the thread-max configurationin the resin.xml. This <code>ScheduleExecutorService</code> isclassloader-safe, so Resin will automatically close your scheduledtasks when restarting a web-app.</p></s2><s2 title="Resin configured resources"><p>All Resin configured resources are available through WebBeans, sinceResin uses WebBeans as its internal registry.</p><p><b><code><bean></code></b> singletons are application-specificcustom services. They are exactly like the <component> beans butdefault to singleton scope. Like <component> they caneither use WebBeans annotations or just be POJO objects.The <bean> tag makes the beans available to any other WebBeanscomponent. The bean default to <code>@Singleton</code> scope, whichmeans that a unique instance is created at Resin start time.The injected type will depend on the <code>class</code> attribute ofthe bean.</p><p><b><code><component></code></b> objects are application-specific custombeans. They can either use WebBeans annotations or just be POJO objects.The <component> tag makes the beans available to any other WebBeanscomponent. The components default to <code>@Dependent</code> scope, whichmeans a new instance is created each time they're referenced or injected.The injected type will depend on the <code>class</code> attribute ofthe bean.</p><p><b><code><database></code></b> is a JDBC pooled database.The <code>name</code> attribute is assigned to the <code>@Named</code>binding. Databases are injected as <code>javax.sql.DataSource</code> types.</p><p><b>EJB stateless beans</b> are automatically registered theWebBeans. The default <code>@Named</code> value is the ejb-name.Stateless beans can use the <ejb-stateless-bean> tag for customconfiguration, or rely on the standard EJB discovery mechanism.Each EJB 3.0 <code>@Local</code> interface is registered separatelyin the WebBeans registry.</p><p><b>EJB stateful beans</b> are automatically registered withWebBeans. The default <code>@Named</code> value is the ejb-name.Stateful beans can use the <ejb-stateful-bean> tag for customconfiguration, or rely on the standard EJB discovery mechanism.Each injection or bean lookup will return a new stateful beanreference, modified by the bean's scope (see below.)Each EJB 3.0 <code>@Local</code> interface is registered separatelyin the WebBeans registry.</p><p><b>EntityManager</b> and <b>EntityManagerFactory</b> objectsfrom JPA are automatically registered with WebBeans. The default<code>@Named</code> value is the <code>persistence-unit</code> name.</p><p><b><env-entry></b> tags register their values withWebBeans. The default <code>@Named</code> value isthe <code>env-entry-name</code>. The registered type is the<code>env-entry-type</code>.</p><p><b><jms-connection-factory></b> automatically registers the configuredfactory with WebBeans. Connection factories can also be configured with <bean> or <resource>,depending on the JMS provider. The registered type is the <code>class</code>of the connection factory, usually <code>javax.jms.ConnectionFactory</code></p><p><b><jms-topic></b> automatically registers the configuredtopic with WebBeans. The default <code>@Named</code> value is thetopic name. Topic can also be configured with <bean> or <resource>,depending on the JMS provider. The registered type is<code>javax.jms.Topic</code></p><p><b><jms-queue></b> automatically registers the configuredqueue with WebBeans. The default <code>@Named</code> value is thequeue name. Queue can also be configured with <bean> or <resource>,depending on the JMS provider. The registered type is<code>javax.jms.Queue</code></p><p><b><remote-client></b> registers remoting clients with WebBeans.The <remote-client> tag will configure the protocol used and theexpected proxy class. The registered type is the API <code>class</code>of the remote service.</p><example title="Example: resin-web.xml for remote-client"><web-app xmlns="http://caucho.com/ns/resin"> <remote-client class="example.HelloService"> <url>hessian:http://localhost:8080/hello/</url> </remote-client></web-app></example><example title="Example: Injecting for remote-client">public class MyServlet extends GenericServlet { @In example.HelloService _hello; ...}</example></s2></s1><s1 title="Application components"><p>The primary value of Resin's dependency injection system is as atype-safe component and service organization registry. Module andcomponent-oriented software has been a goal of software developersfor decades, but in practice developing components and services isa difficult task, in large part because the configuration andassembly of the components has been just ascomplicated as the code itself. There are no silver bullets in software,but the WebBeans registry does significatly reduce the housekeeping codeand XML which gets in the way of good design.</p><s2 title="Annotation-based Component Discovery"><p>At startup, Resin will scan jars and class directories for a<code>META-INF/web-beans.xml</code> file. The presence of that filetells Resin to start scanning all the classes in the jar or directoryfor <code>@Component</code> annotations. Resin will register eachclass with a <code>@Component</code> market with the WebBeans directory.The <code>META-INF/web-beans.xml</code> can be trivial, since its primarypurpose is speeding up startup time by letting Resin scan only the jarswhich contain components. So, applications will generally want to minimizethe number of classes in <code>@Component</code> jars to makestartup fast.</p><example title="Example: META-INF/web-beans.xml"><web-beans xmlns="http://caucho.com/ns/resin"></web-beans></example><p>The component itself can be any Java class. Since Resin manages thecomponent, it can use <code>@In</code> and <code>@Named</code> to injectany other component or resource. Resin will take care of any circulardependencies automatically.</p><example title="Example: Movie.java">import javax.annotation.PostConstruct;import javax.webbeans.Component;@Componentpublic class Movie { private String _title; private String _director; public String getTitle() { return _title; } public void setTitle(String title) { _title = _title; } public String getDirector() { return _director; } public void setDirector(String director) { _director = director; } @PostConstruct public void init() { ... }}</example><p>The <code>@PostConstruct</code> annotation tells Resin to call the<code>init()</code> method once all the injection and configuration iscomplete.</p><p>Any other component or Resin-managed class like servlets can nowuse <code>@In Movie</code> to inject the movie resource.</p><example title="Example: MyServlet.java">import javax.webbeans.In;public class MyServlet extends GenericServlet { @In Movie _movie; ...}</example><p>Most application components will use the <code>@Component</code>discovery mechanism. Except for the <code>META-INF/web-beans.xml</code>marker file, no additional housekeeping code or XML isrequired. As described below, applications can reduce the configurationby one more step with the <code>@New</code> annotationreplacing <code>@In</code>. The target class of the <code>@New</code>annotation is automatically registered with WebBeans even if the classhas no <code>@Component</code> annotation or if the<code>META-INF/web-beans.xml</code> is missing. In other words, any plainJava class can become a part of the WebBeans system without overhead.</p></s2><s2 title="Scopes: @Singleton, @Dependent, @RequestScoped"><p>The scope of the component determines when Resin will create a newcomponent and when it will reuse an old one. Singletons will alwaysreturn the same object, while dependent components will always returna new object instance. Long-lived services will typically be singletons,while scratch-space modules will be dependent components.</p><p>Components default to <code>@Dependent</code> scope. Since manycomponents will be used as pieces of other components,<code>@Dependent</code> is the least-surprising value as a default.</p><p>You can specify a component's scope with an annotation or inthe <code><bean></code> or <code><component></code> tag. Thepredefined scope values are: <code>@Dependent</code>,<code>@RequestScoped</code>, <code>@ConversationScoped</code>,<code>@SessionScoped</code>, <code>@ApplicationScoped</code> and<code>@Singleton</code>.</p><ul><li><code>@Dependent</code> creates a new instance each time.</li><li><code>@RequestScoped</code> creates a new instance for eachservlet request, reusing the instance for the same request.</li><li><code>@ConversationScoped</code> creates a new instance for eachJSF conversation, i.e. for each JSF view page.</li>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -