![]() ![]() ![]() ![]() ![]() ![]() |
The following sections describe developing and managing Spring Framework-based applications for WebLogic Server. In some cases, the information in these sections is described from the perspective of creating MedRec-Spring.
For information on how Oracle supports this release of WebLogic Server and the Spring Framework from SpringSource, see Supported Configurations for Products with Spring Framework.
To demonstrate the ways in which Spring can take advantage of WebLogic Server’s enterprise features, Oracle redesigned the Avitek Medical Records sample application (MedRec) to replace core J2EE components with Spring components.
The following sections describe key steps that Oracle performed when redesigning MedRec. You can use this information if you want to redesign your own J2EE-based WebLogic Server applications to use Spring components. You can also leverage this information if you want to create a new application, based on Spring components, for WebLogic Server.
It is assumed that you are familiar with J2EE concepts, WebLogic Server, and the Spring Framework. For information on WebLogic Server, see WebLogic Server Documentation. For information on the Spring Framework in general, see http://www.springframework.org/.
To transform a J2EE-based application to a Spring-based application, you perform the following steps as desired:
The following sections describe the details of redesigning a J2EE-based application to a Spring-based application. Where appropriate, these sections include sample code. In most cases the sample code is from MedRec-Spring.
In Spring, references to other beans (injected properties) are configured via a Spring configuration XML file, applicationContext-web.xml
.
In MedRec-Spring, Oracle replaced stateless session EJBs with POJOs in the Spring configuration file src\medrecEar\web\WEB-INF\applicationContext-web.xml
as follows:
class="com.bea.medrec.web.patient.actions.ViewRecordAction">
<property name="medRecClientServiceFacade">
<ref bean="medRecClientServiceFacade"/>
</bean>
Then, in the application code, Oracle defined setter methods for the corresponding bean. For example:
protected MedRecClientServiceFacade medRecClientServiceFacade;
public void setMedRecClientServiceFacade(
MedRecClientServiceFacade pMedRecClientServiceFacade){
this.medRecClientServiceFacade = pMedRecClientServiceFacade;
}
To use Spring’s JAX-RPC factory which produces a proxy for Web Services, you configure the Spring JaxRpcPortProxyFactoryBean
by implementing code such as the following; in MedRec-Spring, Oracle implemented this code in the Spring configuration file src\physicianEar\APP-INF\classes\applicationContext-phys-service.xml
.
<!-- reliable asynchronous web service for sending new medical records to medrec -->
<bean id="reliableClientWebServicesPortType"
class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"
lazy-init="true">
<property name="wsdlDocumentUrl" value="http://${WS_HOST}:${WS_PORT}/ws_phys/PhysicianWebServices?WSDL"/>
<property name="portName" value="PhysicianWebServicesPort"/>
<property name="jaxRpcService">
<ref bean="generatedReliableService"/>
</property>
<property name="serviceInterface" value="com.bea.physician.webservices.client.PhysicianWebServicesPortType"/>
<property name="username" value="medrec_webservice_user"/>
<property name="password" value="weblogic"/>
<property name="customProperties"><props>
<prop key="weblogic.wsee.complex">true</prop>
</props>
</property>
</bean>
<> <!-- allows the jaxRpcService class to execute its constructor which loads in type mappings -->
<bean id="generatedReliableService" class="com.bea.physician.webservices.client.PhysicianWebServices_Impl">
</bean>
In this code example, note that:
In Spring, you must configure JMS services so that they are provided to the application during runtime. You can do this via a Spring bean that represents a messaging destination. In MedRec-Spring, Oracle made JMS services available to the application at runtime by implementing the following code in the Spring configuration file src\medrecEar\APP-INF\classes\applicationContext-jms.xml
.
<bean id="uploadQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="com.bea.medrec.messagging.MedicalRecordUploadQueue"/>
</bean>
<bean id="jmsConnFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="com.bea.medrec.messagging.MedRecQueueConnectionFactory"/>
</bean>
<bean id="uploadJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="jmsConnFactory"/>
</property>
<property name="defaultDestination">
<ref bean="uploadQueue"/>
</property>
</bean>
You can expose WebLogic Server’s MBean Server to Spring through Spring’s MBeanServerConnectionFactoryBean
, which is a convenience factory that produces an MBeanServerConnection
that is established and cached during application deployment and can later be operated on by referencing beans. The MBeanServerConnectionFactoryBean
can be configured to return the WebLogic Server Runtime MBean Server, and to obtain a connection to the WebLogic Server Domain Runtime MBean Server and the WebLogic Server Edit MBean Server.
Note: | Because the WebLogic Server Domain Runtime MBean Server is not active during deployment, you must configure the MBeanServerConnectionFactoryBean to use Spring’s lazy instantiation. Lazy instantiation fetches the Spring bean when it is invoked. |
Exposing the WebLogic Server Runtime MBean Server Connection to Spring is demonstrated in the following code example, which, in MedRec-Spring, Oracle implemented in the Spring configuration file medrecEar/APP-INF/classes/applicationContext-jmx.xml
.
<> <!-- expose weblogic server's runtime mbeanserver connection -->
<bean id="runtimeMbeanServerConnection" class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
<property name="serviceUrl" value="service:jmx:t3://${WS_HOST}:${WS_PORT}/jndi/weblogic.management.mbeanservers.runtime"/>
<property name="environment">
<props>
<prop key="java.naming.security.principal">${WS_USERNAME}</prop>
<prop key="java.naming.security.credentials">${WS_USERNAME}</prop>
<prop key="jmx.remote.protocol.provider.pkgs">weblogic.management.remote</prop>
</props>
</property>
</bean>
In MedRec-Spring, Oracle used a datasource that references a JDBC connection pool that is managed by WebLogic Server and also employed Spring’s JdbcDaoSupport
class. For information on JdbcDaoSupport
, see the Spring documentation.
For an example of the way in which Oracle implemented JDBC, see the MedRec-Spring class
src\medrecEar\dao\com\bea\medrec\dao\jdbc\JdbcPatientDao.java
See also the following code examples, which, for MecRec-Spring, Oracle implemented in the Spring configuration files src\medrecEar\APP-INF\classes\applicationContext-db.xml
and src\medrecEar\APP-INF\classes\applicationContext-jdbc.xml
, respectively.
applicationContext-db.xml
code example:
<!-- datasource pool -->
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MedRecGlobalDataSourceXA"/>
</bean>
applicationContext-jdbc.xml
code example:
<bean id="patientDao"
class="com.bea.medrec.dao.jdbc.JdbcPointBasePatientDao"
autowire="byType"/>
Additionally, in MedRec-Spring, Oracle replaced entity EJBs with POJOs and made use of Spring JDBC for persistence. For an example, see the MedRec-Spring class \src\medrecEar\core\com\bea\medrec\domain\Address.java
Spring supports distributed transactions through WebLogic Server’s JTA implementation. You can also configure the Spring transaction manager to delegate responsibility to the WebLogic Server JTA transaction manager. This is accomplished via Spring’s WebLogicJtaTransactionManager
class. Oracle used this approach with MedRec-Spring in order to exactly mirror transaction management in the original version of MedRec.
To use the Spring transaction abstraction layer for transaction management and delegate responsibility to the WebLogic Server JTA transaction manager, you implement code such as the following, which Oracle implemented in the Spring configuration files src\medrecEar\APP-INF\classes\applicationContext-tx.xml
and src\medrecEar\APP-INF\classes\applicationContext-service.xml
, respectively.
applicationContext-tx.xml
code example:
<!-- spring's transaction manager delegates to WebLogic Server's transaction manager -->
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName"
value="javax.transaction.TransactionManager"/>
</bean>
applicationContext-service.xml
code example:
<!-- base transaction proxy for which medrec spring beans inherit-->
< bean id="baseTransactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="activate*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="compose*">PROPAGATION_REQUIRED</prop>
<prop key="deny*">PROPAGATION_REQUIRED</prop>
<prop key="getRecord*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="getPatient*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="getLog*">PROPAGATION_NOT_SUPPORTED</prop>
<prop key="process*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="send*">PROPAGATION_REQUIRED</prop>
</props>
</property>
< /bean>
<!-- single point of service for all medrec clients -->
<bean id="medRecClientServiceFacade"
parent="baseTransactionProxy">
<property name="target">
<bean class="com.bea.medrec.service.MedRecClientServiceFacadeImpl">
<property name="adminService">
<ref bean="adminService"/>
</property>
<property name="patientService">
<ref bean="patientService"/>
</property>
<property name="recordService">
<ref bean="recordService"/>
</property>
<property name="recordXmlProcessorService">
<ref bean="recordXmlProcessorService"/>
</property>
</bean>
</property>
</bean>
The transactionAttributes
you specify define the way in which Spring begins and ends transactions. Because MedRec-Spring delegates transaction management to WebLogic JTA, management tasks such as transaction suspension and rollback are handled as specified by WebLogic’s transaction manager.
For more information on WebLogicJtaTransactionManager
, see the Oracle Technology Network Web site.
Spring applications can take advantage of WebLogic Server’s clustering features. Because most Spring applications are packaged as Web applications (.war files), you need do not need to do anything special in order to take advantage of WebLogic Server clusters; all you need to do is deploy your Spring application to the servers in a WebLogic Server cluster.
The certification of Spring 1.2.8 and 2.0 on WebLogic Server extends the Spring JndiRmiProxyFactoryBean
and its associated service exporter so that it supports proxying with any J2EE RMI implementation. To use the extension to the JndiRmiProxyFactoryBean
and its exporter:
<bean id="proProxy" class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<property name="jndiName" value="t3://${serverName}:${rmiPort}/order"/>
</property>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.url.pkgs">weblogic.jndi.factories</prop>
</props>
</property>
<property name="serviceInterface" value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
</bean>
<bean id="order-pro" class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
<property name="service" ref="petStore"/>
<property name="serviceInterface" value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
<property name="jndiName" value="order"/>
</bean>
The WebLogic Server security system supports and extends Java EE security while providing a rich set of security providers that you can be customize to integrate with different security databases or security policies.
As described at the
Spring Security Web site, Acegi Security is now Spring Security, the official security project of the Spring Portfolio. The Spring security (acegi) framework provides security
to a Spring application and includes a rich set of security providers.
The question then becomes how to integrate the two security frameworks.
For a combined J2EE and Spring application, rather than require authentication with both security frameworks, WLS security and Spring security work together. WLS security handles the authentication via the default Authentication provider for the security realm, and converts WLS principals to Spring GrantedAuthority principals through a mapper class. Once authenticated by WLS security, a user is authenticated for Spring security. You can then decide how to secure the objects in the application. One common practice is to secure Java EE resource with Weblogic security and secure Spring resource with Spring security.
As described in the Spring Security Reference, Container Adapters enable Acegi Security to integrate directly with the containers used to host end user applications, in this case WebLogic Server.
The integration between a container and Acegi Security is achieved through an adapter. The adapter provides a container-compatible user authentication provider, and needs to return a container-compatible user object.
applicationContext-acegi-security.xml is the configuration file for Spring security. For WebLogic Server, WeblogicAuthenticationFilter is added to the list of filters in applicationContext-acegi-security.xml. This filter is responsible for converting the Weblogic principals to Spring GrantedAuthority subjects, based on the mapper. The mapper is configured as a property for the WeblogicAuthenticationFilter, and it is injected at creation time.
The following is an example of the mapper class.
public class MyAuthorityGranter implements AuthorityGranter {
public Set grant(Principal principal) {
Set rtnSet = new HashSet();
if (principal.getName().equals("fred@oracle.com")) {
rtnSet.add("ROLE_SUPERVISOR");
rtnSet.add("IS_AUTHENTICATED_ANONYMOUSLY");
}
return rtnSet;
}
}
In this example, user fred@oracle.com
in the WebLogic domain is mapped to ROLE_SUPERVISOR
and IS_AUTHENTICATED_ANONYMOUSLY
.
The following code is added to web.xml
to plug in the applicationContext-acegi-security.xml
file:
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/main/secure/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-
class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-acegi-security.xml
</param-value>
</context-param>
A standard WebLogic Server installation provides standard Java EE 5 dependency injection and interceptors (a form of aspect-oriented programming) in the WebLogic Server Java EE container. WebLogic Server also supports a Spring Framework extension that provides enhanced dependency injection and aspect-oriented programming features in the container. This extension uses Pitchfork, a Spring Framework add-on that provides JSR-250 (Common Annotations), dependency injection, and EJB 3.0 style interception. The extension provides dependency injection and aspect-oriented programming to EJB instances and Web components that include the servlet listener and filter.
Note: | JSP tag handlers do not support the Spring extension in this release of WebLogic Server. |
To enable the Spring extension with WebLogic Server, do the following:
You must have at least the following jar files:
The WebLogic Server Web container and EJB container use these jars to provide container service (dependency injection and interceptor).
Applications (packaged as ear, war, or jar files) use these jars because they are in the server classpath. You can configure your application to use the version of jars packaged with the application if you enable certain of the deployment descriptors.
<component-factory-class-name>
element to org.springframework.jee.interfaces.SpringComponentFactory
. This element exists in EJB, Web, and application descriptors. A module level descriptor overwrites an application level descriptor. If the tag is set to null (default), the Spring extension is disabled. spring-ejb-jar.xml
or spring-web.xml
, and place it in the /WEB-INF/classes/META-INF directory of your application (or put the META-INF directory in a jar file). These are the standard Spring bean definition files with the names that the Weblogic container searches for. For the Spring container to be aware of the EJB or servlet instance, the <id>
tag of the Spring bean must be set to the ejb-name
for EJB or the class-name
of the web components.
You can use an extension to the WebLogic Server Administration Console to monitor Spring bean attributes that are defined in applications.
The Spring console extension is based on RuntimeMBeans registered using the WebLogic Server infrastructure. The console extension displays configuration information for deployed Spring beans.
In the current release, the Spring console extension works with Web applications but not EJBs.
To use the Spring console extension, you must turn on support for Spring beans and enable the Spring console extension, as follows:
WL_HOME/
server/lib/weblogic-spring.jar
to WebLogic Server, where WL_HOME
refers to the main WebLogic Server installation directory, such as \beahome/wlserver_10.3
. You only need to perform this step once for your WebLogic Server instance. This jar file is a Java EE optional package used by an application ( packaged as an ear or war file) to create the MBeans for the application during its deployment.
Deploy weblogic-spring.jar
either of the following ways:
WL_HOME
\server\lib
. java weblogic.Deployer -library -deploy – source
WL_HOME
/server/lib/weblogic-spring.jar – targets
server_name
-adminurl
server_URL
-user
user_name
-password
password
weblogic-spring.jar
as a Java EE optional package. Do this to each Spring application you want to make use of the Spring runtime MBeans or Spring console extension
Do this by adding the following lines to your META-INF/Manifest.mf
:
Extension-List: WeblogicSpring
WeblogicSpring-Extension-Name: weblogic-spring
WeblogicSpring-Specification-Version: 10.3.0.0
WeblogicSpring-Implementation-Version: 10.3.0.0
weblogic-spring.jar
must be added as a listener to the root Spring context. This can be done in two ways. The first way is preferred. web.xml
to change the Spring context loader listener to the WebLogic context loader listener. That is, change this:<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
<listener-class>
weblogic.spring.monitoring.WeblogicContextLoaderListener
</listener-class>
WeblogicContextLoaderListener extends the Spring ContextLoaderListener and adds WeblogicSpringApplicationListener as an ApplicationListener and a BeanFactoryPostProcessor to the Web application context.
In your Web application Spring XML configuration file add:
<bean class="weblogic.spring.monitoring.WeblogicSpringApplicationListener " />
To access Spring beans that are not MBeans through the WebLogic Administration Console, you must configure an MBeanExporter in the applicationContext.xml
file and specify which beans to expose via the assembler. Make sure that the applicationName
property is the deployed name of your application.
![]() ![]() ![]() |