Singleton Class
Singleton Class is created to maintain only one instance of this class object made available for application's ClassLoader. To achieve this, we have to add restrictions for this class access
- All Constructors has to have private as access modifier
- One factory pattern based, means atleast one public static method defined to create instance of this class
- One static variable defined to hold this singleton object
- Factory method has to be implemented gurantteing to not to create instance more than once.
public static SingletonClass getInstance(){ if(null == ins1) { ins1=new SingletonClass(); } return ins1; }
- To achieve thread safe, this getInstance() method has to use synchronized in method.
Singleton offers lots of advantage in creating instance in Application Context. In multi-threaded environment, if this synchronized getInstance() method called parallely then performance will be beaten heavily. Instance creation happens very early start up time of application, once object instanciated, then we have to avoid this if check and synchronized block execution. How to synchronized block in singleton class object instanciation ?
To answher the above question, we have to assign getInstance() result to the above mentioned static variable.
public static SingletonClass ins = getInstance();
However, this instance has to be initialized based on the argument passed then this could be painful job in creating instance and making it thread safe. Even we can build additional logic to achieve this, however, if an application comes with more number of singleton objects and Object lifecycle also be clearly maintained or controlled, then it is really more pain. We will end up spending time in this logic rather than in real business of application. Various tools available in market to provide application infrastructure runtimes. Eg: SpringSource
Java Enterprise Edition 5
Java EE 5 comes with Resource Injection concept, offers ease way of assigning object reference to the fields in a Class.
- JSR 250 - Common annotations: Common Annotations for the Java Platform Specification, provides the semantics of the platform's common annotations.
- JSR 220 - EJB beans: the Enterprise JavaBeans 3.0 Specification, Section 8.1, Annotation of Context Dependencies.
- JSR 224 - Web services: the Java API for XML-Based Web Services (JAX-WS) 2.0 Specification, javax.xml.ws.WebServiceRef.
- JSR 255 - JMX 2.0, Remote API for JMX, uses JSR 250 common annotations
public static DataSource catalogDS=null;
public synchronized javax.sql.DataSource getCatalogDS() {
try {
if(null == catalogDS)
{
// Obtain the initial Java Naming and Directory Interface
// (JNDI) context.
InitialContext initCtx = new InitialContext();
// Perform JNDI lookup to obtain the resource.
catalogDS = (DataSource)
initCtx.lookup("java:comp/env/jdbc/catalogDS");
}
} catch (NamingException ex) {
// Handle failure.
}
return catalogDS;
}
...
public getProductsByCategory() {
// Get the DataSource.
DataSource catalogDS = getCatalogDS();
// Get a connection and execute the query.
Connection conn = catalogDS.getConnection();
...
}
In web.xml:
<resource-ref>
<description>Catalog DataSource</description>
<res-ref-name>jdbc/catalogDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
In the above code, getCatalogDS() will be called DAO design pattern methods to get a connection from DataSource. Establishing or making available this DataSource resource to the application mostly one time job in nature. But here in the above code, getCatalogDS() called everytime methods in DAO Class called.
In web Application, all possible resources are defined in web.xml with resource type. The same will be accessed from application like the way in sample code. Using resource injection, we can achieve this by placing annotation above the field
private @Resource DataSource catalogDS;
public getProductsByCategory() {
// Get a connection and execute the query.
Connection conn = catalogDS.getConnection();
...
}
No additional details required to be mentioned in web.xml. If we have multiple Datasource resource mentioned in web.xml, then we need to specify additional details in @Resource annotation.
- Common annotations
- @Resource
- @Resources
- @DeclaresRoles
- @RunAs
- @PostConstruct
- @PreDestroy
- EJB beans
- @PersistenceContext
- @PersistenceContexts
- @PersistenceUnit
- @PersistenceUnits
- Web services
- @WebServiceRef
- @WebServicesRefs
Refer TechNote
JMX 2.0 API: MBeanRegistration
javax.management.MBeanRegistration interface allows user to perform pre or post MBeanServer registration or unregistration. We can achieve this by making resource injection. Right now, this available only for the class or subclass of MBeanServer, ObjectName, or SendNotification in JMX 2.0 API.
public Configuration implements ConfigurationMBean {
@Resource
private volatile MBeanServer mbeanServer;
@Resource
private volatile ObjectName objectName;
...
void unregisterSelf() throws Exception {
mbeanServer.unregisterMBean(objectName);
}
@Resource
private volatile SendNotification sender;
...
private void updated() {
Notification n = new Notification(...);
sender.sendNotification(n);
}
@Resource(type = MBeanServer.class)
private volatile MBeanServerConnection mbsc;
}
Note: A field to be injected must not be static. It is recommended that such fields be declared volatile.
No comments:
Post a Comment