Is a declarative service a singleton by default? - osgi

The configuration:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" immediate="true" name="printing">
<implementation class="printing.PrinterManager"/>
<service>
<provide interface="service.printing.IPrinterManager"/>
</service>
</scr:component>
The class:
public class PrinterManager implements IPrinterManager {
public void activate(BundleContext ctx) {
System.err.println("hello");
}
public void deactivate(BundleContext ctx) {
System.err.println("bye");
}
}
When I inject an object of that class somewhere else in my code like this:
#Inject
IPrinterManager pm;
Do I always get the same instance of that class or not?
How to make that instance a singleton with the help of osgi/equinox facilities if it's not a singleton already? (I know how to write a singleton the java/vanilla way, that's not my question)

Yes a DS component is a singleton by default. See Multiple Component Instances with OSGi Declarative Services

Related

How to use beans instead of static classes in facelets taglibs?

Is it possible to use methods of spring beans instead of static methods when defining tag-lib functions?
At the moment the application only uses static methods of abstract classes:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd"
version="2.2">
<namespace>http://my/security/facelets/tags</namespace>
<function>
<function-name>isRegion</function-name>
<function-class>my.NovaFaceletsAuthorizeTagUtils</function-class>
<function-signature>boolean isRegion()</function-signature>
</function>
No, but you can delegate to bean methods. For instance, like this:
public static boolean isRegion() {
getCurrentApplicationContext().getBean(RegionService.class).isRegion();
}
There are various approaches for getting the current ApplicationContext, depending on how you're bootstrapping it, and how many ApplicationContext you have. For an overview of relevant techniques, see:
Spring get current ApplicationContext
In simple cases, where the bean is application scoped and doesn't have AOP advice (in particular, no #Transactional), it might be easier to put the bean itself into a static field:
#Component
public class RegionService {
private static RegionService instance;
public RegionService() {
instance = this;
}
public static RegionService getInstance() {
return instance;
}
}
so you can use RegionService.getInstance() to access the bean from anywhere.

How to pass base package as a variable inside pointcut expression in Spring AOP?

I am creating a java library for logging purpose so that if any application uses my library then spring AOP's advices are applied to each method of the application. But in my library, I don't know the base package of the applications that will be using it. So, the applications should specify their base package in the application.properties file and my library will use it and put it in my pointcut as a variable. But seems like pointcut expressions only accepts contants inside it.
I don't want to go for annotation based approach.
#Component
#Aspect
#Slf4j
public class LoggingAop {
#Value("${base.package}")
String basePackage;
#Pointcut("within("+basePackage+"..*)") //error
public void logAllMethods()
{
}
}
Answers for the following questions explains why this is not possible with annotation based Spring AOP configuration
Get rid of "The value for annotation attribute must be a constant expression" message
How to supply value to an annotation from a Constant java
Spring boot supports xml based configurations and the requirement can be achieved as follows.
Assuming we have to intercept all the method calls within base package com.app.service
Have an entry in resources/application.properties.
base.package=com.app.service
An Aspect to log method calls within the base package can be as follows
package com.app.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogAspect {
Logger log = LoggerFactory.getLogger(LogAspect.class);
public Object logAllMethods(ProceedingJoinPoint pjp) throws Throwable {
log.info("Log before method call");
try {
return pjp.proceed();
}finally {
log.info("Log after method call");
}
}
}
The aop configuration can be defined as follows .
File : resources/aop-application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="logAspect" class="com.app.aspect.LogAspect"></bean>
<aop:config>
<aop:aspect id="logallaspect" ref="logAspect" >
<!-- #Around -->
<aop:pointcut id="logAllMethodsAround" expression="within(${base.package}..*)" />
<aop:around method="logAllMethods" pointcut-ref="logAllMethodsAround" />
</aop:aspect>
</aop:config>
</beans>
Do note that the pointcut expression is constructed with the application.properties entry.
Remember to load the aop-application-context.xml as follows
#SpringBootApplication
#ImportResource("classpath:aop-application-context.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The above code will advice all the interceptable Spring bean method calls within the defined base package and logs them .
Hope this helps.

Maven, CDI (WELD) and interfaces packages

first of all, I'm not an expert in this subject, that's why I'm asking ...
I have two Maven modules, both exposing several interfaces. One module deals with the business logic (BL), the other one is a gateway to external systems (GW).
As long as the gateway serves as outgoing gateway, there is no problem with circular dependencies as it is like this:
BL =depends=> GW
The interfaces of the gateway are injected into the business logic by #Inject, everything works fine.
Module: BusinessLogic:
public class BusinessLogicBean {
#Inject private GatewayInterface interface;
public void sendStuff(Param myParam) {
interface.doSend(myParam);
}
Module: Gateway
public Interface GatewayInterface {
void doSend(Param someParam);
public class GatewayInterfaceBean {
public void doSend(Param someParam) {
//implementation goes here
As soon as I have incoming invocations which needs to be delegated to the business logic I can't specify:
BL =depends=> GW =depends=> BL
as Maven will complain about cirdular dependencies.
Therefore I decided to have a dedicated interfaces module of the gateway, so the dependencies are as follows:
BL =depends=> I_GW <=depends= GW =depends=> BL
So far so good despite of the fact, that #Inject right now complaints about unresolved dependencies, the same code as above isn't working anymore.
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type OrderProcess with qualifiers #Default
at injection point [BackedAnnotatedField] #Inject private de.xyz.abc.externalaccess.control.AccessServiceBean.process
at de.xyz.abc.externalaccess.control.AccessServiceBean.process(AccessServiceBean.java:0)
This is how the modules look like:
Module: BusinessLogic:
public class BusinessLogicBean {
#Inject private GatewayInterface interface;
Module: Interfaces_Gateway
public Interface GatewayInterface {
void doSend(Param someParam);
Module: Gateway
public class GatewayInterfaceBean {
public void doSend(Param someParam) {
//implementation goes here
public class ProvisioningServiceTest {
private static SeContainer container;
private static ProvisioningService service;
#Test
public void testPostApplications() {
service.postApplications(null);
}
#BeforeClass
public static void setUp() {
SeContainerInitializer weld = Weld.newInstance();
container = weld.initialize();
service = container.select(ProvisioningService.class).get();
}
#AfterClass
public static void shutDown() {
container.close();
}
}
The bang happens within #BeforeClass, which part am I missing? As long as the interface and the implementation resides in the same module, everything is fine, but as soon as I split it into two modules ...
beans.xml (in all three modules within META-INF:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
<interceptors>
<class>de.abc.util.interceptor.CallTracingInterceptor</class>
<class>de.abc.util.interceptor.PerformanceTracingInterceptor</class>
<class>de.abc.util.interceptor.ValidationInterceptor</class>
</interceptors>
</beans>
WELD 3.1.1
BTW, using this approach with WildFly and the #EJB annotation doesn't cause a problem at all, but Wildfly unfortunately is no option here.
Thanks for any hint.
If possible, one bean in the chain of dependencies should be #ApplicationScoped or #SessionScoped. The references will be proxies, which can be resolved as soon as necessary at runtime.

bean scope in xml not working

singleton bean scope in XML spring not working.only prototype working.Even without any scope tag prototype is working.
XML snippet:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="restaurant" class="bean_scope.Restaurant1" scope="singleton"> <!-- scope="singleton" -->
</bean>
</beans>
Java class for setter methods:
package bean_scope;
public class Restaurant1 {
private String welcomeNote;
public void setWelcomeNote(String welcomeNote) {
this.welcomeNote = welcomeNote;
}
public void greetCustomer(){
System.out.println(welcomeNote);
}
}
Java Spring Test class:
package bean_scope;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Restaurant1Test {
public static void main(String[] args) {
Restaurant1 restaurantOb1=(Restaurant1) new ClassPathXmlApplicationContext("bean_scope/SpringConfig1.xml")
.getBean("restaurant");
restaurantOb1.setWelcomeNote("Welcome");
restaurantOb1.greetCustomer();
Restaurant1 restaurantOb2=(Restaurant1) new ClassPathXmlApplicationContext("bean_scope/SpringConfig1.xml")
.getBean("restaurant");
//restaurantOb2.setWelcomeNote("Hello");
restaurantOb2.greetCustomer();
}
}
Output:
Welcome
null
Please help me with this why singleton scope is not working
Since you create two independent instances of ClassPathXmlApplicationContext, each one will have its own singleton instance of the bean. The singleton scope means there will only be one instance of the bean within the Spring context - but you have two contexts there.
This would produce the result you're expecting:
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean_scope/SpringConfig1.xml");
Restaurant1 restaurantOb1=(Restaurant1) ctx.getBean("restaurant");
restaurantOb1.setWelcomeNote("Welcome");
restaurantOb1.greetCustomer();
Restaurant1 restaurantOb2=(Restaurant1) ctx.getBean("restaurant");
//restaurantOb2.setWelcomeNote("Hello");
restaurantOb2.greetCustomer();

Dependency Injection in Spring?

How can we know if spring framework is using constructor based dependency injection or setter method based dependency injection, when both the constructor and setter method is defined?
for example.. I have two java classes as follows..
TextEditor.java
public class TextEditor {
private SpellChecker spellChecker;
TextEditor(SpellChecker spellChecker){
this.spellChecker = spellChecker;
}
public void setSpellChecker(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
and
SpellChecker.java
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling(){
System.out.println("Inside checkSpelling." );
}
}
in configuration file, pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Definition for textEditor bean using inner bean -->
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
<property name="spellChecker">
<bean id="spellChecker" class="SpellChecker"/>
</property>
</bean>
</beans>
now, how can we know that spring has added dependency using Constructor or using Setter method?
When using a <property>, spring injects dependencies via setter.
If you want to inject it via constructor, you use <constructor-arg>.
Also see: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-collaborators
It is all about developer choice how does he/she configure spring to inject dependency.
Since everyone could write big wall of text about how Dependency Injection works you should see/read this:
http://www.journaldev.com/2410/spring-dependency-injection-example-with-annotations-and-xml-configuration

Resources