Please find the class structure as below and help to find anything missing here.
Unable to get the SOP mentioned in the before method.
public class HijackBeforeMethod implements MethodBeforeAdvice {
#Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("BEFORE METHOD CALL : additional concern before actual logic");
System.out.println("Method : " + arg0);
}
}
The Main class as below
#RestController
public class A {
#Autowired
Dao b;
...
b.print(); //This should call the before method
}
The Dao class as below
Public class DaoImpl implements Dao{
#Autowired
Datasource ds
public void print(){
.....
}
}
the rest-servlet.xml context file entries as below
<bean id="hijackBeforeMethodBean" class="com.scb.cadm.aop.HijackBeforeMethod" />
<bean id="b" class="DaoImpl"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">/>
<property name="target" ref="b"></property>
<property name="interceptorNames">
<list>
<value>hijackBeforeMethodBean</value>
</list>
</property>
</bean>
I found the issue..
Instead of
#Autowired
Dao b;
I have use the proxy bean
#Autowired
Dao proxy;
Related
I have a bit of code that is working :
#Component
public class MessageUtil {
#Autowired
#Qualifier("processMessages")
private ReloadableConfig config;
public String createMessage() {
return config.getPropertyStr("message.simple.signature");
}
}
The bean processMessages is defined here :
<bean id="processMessages" class="com.company.framework.resources.ReloadableConfig">
<property name="basename" value="classpath:com/company/aaa/bbb/domain/service/processMessages"/>
<property name="defaultEncoding" value="UTF-8"/>
<property name="cacheSeconds" value="60"/>
</bean>
Then I created some new classes :
public abstract class MessageBuilder {
#Autowired
#Qualifier("processMessages")
protected ReloadableConfig config;
public abstract String createMessage();
}
#Component
public class SimpleMessageBuilder extends MessageBuilder {
private String template;
private void setTemplate() {
template = config.getPropertyStr("message.simple.signature");
}
#Override
public String createMessage() {
setTemplate();
return template;
}
}
I now have a NullPointerException because in setTemplate(), config is null.
What's the problem in the second code ?
#Autowired doesn't work neither on field neither on constructors of abstract classes. It works on setter of abstract class but be sure to make it final because if overwritten by concrete class behavior is unstable. An abstract class isn't component-scanned since it can't be instantiated without a concrete subclass.
I found many solutions to this issue, and choose the below one.
But it still gets NullpointerException, what's wrong?
A Class
#Component
public class A {
private static Foo foo;
#Autowired
public void setFoo(Foo foo) {
A.foo = foo;
}
public static someFunction() {
foo.doSomething();
}
}
B Class
#Service
public class B {
public void someFunction() {
A.someFunction();
}
}
You cannot auto-wire static properties in Spring, Static fields are instantiated during class load as they are the properties of the class while auto wired attributes work after spring initializes the beans.
Although you may use MethodInvokingFactoryBeanin Spring to achieve what you wanted.
some example would be in XML as below
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="foo.bar.Class.setTheProperty"/>
<property name="arguments">
<list>
<ref bean="theProperty"/>
</list>
</property>
</bean>
Edit :- without XML
inside your #Configuration class
do
#Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setStaticMethod("MyClass.staticMethod");
return methodInvokingFactoryBean;
}
let me know in case you need more help.
I read, that in XML-based Spring configuration beans can inherit factory method.
I tried to implement it:
Controller interface:
public interface Controller {
String method();
}
ControllerFactory class:
public class ControllerFactory {
public Controller getController(String controllerName){
switch(controllerName){
case "OtherController":
return new OtherController();
case "SampleController":
return new SampleController();
default:
throw new IllegalArgumentException("Wrong controller name.");
}
}
}
SampleController implementation:
public class SampleController implements Controller {
#Override
public String method() {
return "SampleController";
}
}
OtherController implementation:
public class OtherController implements Controller {
#Override
public String method() {
return "OtherController";
}
}
But the following XML configuration:
<!--factory method inheritance -->
<bean id="controllerFactory" class="factory.ControllerFactory"/>
<bean id="parentController" abstract="true" factory-bean="controllerFactory" factory-method="getController"/>
<bean id="otherController" parent="parentController">
<constructor-arg index="0" value="OtherController"/>
</bean>
Gives compile-time error:
No matching constructor found in class 'Controller'
How can I change it to have factory method bean inheritance implemented properly?
Copying factory-method configuration to child bean works as expected:
<bean id="otherController" parent="parentController" factory-bean="controllerFactory" factory-method="getController">
<constructor-arg index="0" value="OtherController"/>
</bean>
Change bean with id parentController as follows:
<bean id="parentController" class="factory.ControllerFactory" factory-bean="controllerFactory" factory-method="getController">
<constructor-arg index="0" value="OtherController"/>
</bean>.
Try this it may work.
consider the following code:
public abstract class MachineInPitImpl extends AbstractPersistentObject implements MachineInPit {
protected PersonReference currentOperatorRef;
public void setCurrentOperatorRef(PersonReference currentOperatorRef) {
this.currentOperatorRef = currentOperatorRef;
this.currentOperatorObj = null;
}
public PersonReference getCurrentOperatorRef() {
return currentOperatorRef;
}
The above class is not wired with spring context, I need to extend this class and grab the values in the get method of this class in my new class.
I have wrote a class as this:
public class MachineOPJMXBeanImpl extends MachineInPitImpl {
public MachineOPJMXBeanImpl(){
}
#Override
public PersonReference getCurrentOperatorRef() {
return super.getCurrentOperatorRef();
}
}
But the value in this class get method is null.Why am I getting null value?
Here is the applicationcontext.xml file:
<bean id="machineOPJMXBean"
class="com.mincom.works.cc.personnel.node.MachineOPJMXBeanImpl" parent="machineInPitImpl">
<property name="currentOperatorRef" ref="currentOperatorRef"/>
</bean>
<bean id="machineInPitImpl" class="minestar.pitlink.domain.pitmodel.MachineInPitImpl" abstract="true" scope="singleton" lazy-init="true">
<property name="currentOperatorRef" ref="currentOperatorRef"/>
</bean>
<bean id="currentOperatorRef" class="minestar.machinetracking.domain.PersonReference"/>
applicationContext
<bean id="contentRegisteringBean" parent="abstractRegisteringBean" lazy-init="false">
<property name="processor">
<bean class="com.somepackage.ContentService$Processor"/>
</property>
</bean>
<bean id="abstractRegisteringBean" class="test.spring.MockFactoryBean">
<property name="type" value="com.somepackage.ProcessorRegisteringBeanImpl"/>
</bean>
ProcessorRegisteringBeanImpl
public class ProcessorRegisteringBeanImpl {
private Processor mProcessor;
public Processor getProcessor() {
return mProcessor;
}
public void setProcessor(final Processor processor) {
mProcessor = processor;
}
}
MockFactoryBean.java
public class MockFactoryBean<T> implements FactoryBean<T> {
private Class<T> type;
public void setType(Class<T> type) {
this.type = type;
}
#Override
public T getObject() throws Exception {
return Mockito.mock(type);
}
#Override
public Class<T> getObjectType() {
return type;
}
#Override
public boolean isSingleton() {
return true;
}
}
Exception:
org.springframework.beans.NotWritablePropertyException: Invalid
property 'processor' of bean class
[test.spring.MockFactoryBean]: Bean property 'processor' is
not writable or has an invalid setter method. Does the parameter type
of the setter match the return type of the getter?
When you declare a FactoryBean, Spring expects that you configure properties of the FactoryBean rather than properties of the object it creates.
Try the following instead:
<bean id="contentRegisteringBean" parent="abstractRegisteringBean" lazy-init="false">
<!-- Define concrete class to pass to Mockito.mock() -->
<constructor-arg value = "com.somepackage.ProcessorRegisteringBeanImpl" />
<property name="processor">
<bean class="com.somepackage.ContentService$Processor"/>
</property>
</bean>
<!-- Abstract definition of beans created using Mockito.mock() -->
<bean id="abstractRegisteringBean" abstract = "true"
class="org.mockito.Mockito" factory-method = "mock">
</bean>