Is there any posibilities to autowire Spring bean

2019-08-02 09:16发布

问题:

I tried to use recommendations and put these annotations in zkoss controller, but even with these code, spring services didnt initialized and i got NullPointer. My code.

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class UserNotesListController extends SelectorComposer<Component> {
private static final long serialVersionUID = 1L;
private static final Logger log = 
LoggerFactory.getLogger(UserNotesListController.class);

@WireVariable
private UserService userService;
@WireVariable
private NoteService noteService;

private ListModel<Note> notesListModel;

@Wire
private Window window;

public UserNotesListController() {
    notesListModel = new ListModelList<>(noteService.listNotes());
    ((ListModelList<Note>) notesListModel).setMultiple(true);
    log.info("Конструктор класса {} успешно создан", UserNotesListController.class.getSimpleName());
}

public ListModel<Note> getNotesListModel() {
    return notesListModel;
}

@Listen("onSelect = notesListBox")
public void updateRow() {
    Set<Note> selectedNotes = ((ListModelList<Note>) notesListModel).getSelection();
    int size = selectedNotes.size();

    showNotify(size > 0 ? size + " notes selected: " + selectedNotes : "no notes selected", window);
}

private void showNotify(String message, Component reference) {
    Clients.showNotification(message, "Info", reference, "top_right", 2000, true);
}

}

java.lang.NullPointerException
ru.mightynoobs.springhibernate.controller.UserNotesListController.<init>(UserNotesListController.java:44)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:423)
java.lang.Class.newInstance(Class.java:442)
org.zkoss.zk.ui.impl.AbstractUiFactory.newComposer(AbstractUiFactory.java:130)
org.zkoss.zk.ui.impl.AbstractUiFactory.newComposer(AbstractUiFactory.java:142)
org.zkoss.zk.ui.impl.Utils.newComposer(Utils.java:90)
org.zkoss.zk.ui.metainfo.ComponentInfo.toComposer(ComponentInfo.java:355)
org.zkoss.zk.ui.metainfo.ComponentInfo.toComposers(ComponentInfo.java:323)
org.zkoss.zk.ui.metainfo.ComponentInfo.resolveComposer(ComponentInfo.java:310)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:834)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:826)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:735)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:797)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:757)
org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:699)
org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:442)
org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:356)
org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:217)
org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:136)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)

=======

<?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:tx="http://www.springframework.org/schema/tx"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="ru.mightynoobs.springhibernate"/>

<!--Database information-->
<bean id="originalDataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url"
              value="jdbc:mysql://localhost:3306/mightynoobsdb"/>
    <property name="username" value="root"/>
    <property name="password" value="admin"/>
</bean>
<!--for log4JDBC-->
<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource" >
    <constructor-arg ref="originalDataSource" />
    <property name="logFormatter">
        <bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter" >
            <property name="loggingType" value="SINGLE_LINE" />
            <!--<property name="margin" value="19" />--> <!-- на этой строчке Spring выдает ошибку - не может прочитать значение value -->
            <property name="sqlPrefix" value="SQL:::" />
        </bean>
    </property>
</bean>

<!--Hibernate 4 SessionFactory Bean definition-->
<bean id="sessionFactory"
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="annotatedClasses">
        <list>
            <value>ru.mightynoobs.springhibernate.model.user.User</value>
            <value>ru.mightynoobs.springhibernate.model.user.Role</value>
            <value>ru.mightynoobs.springhibernate.model.note.NoteState</value>
            <value>ru.mightynoobs.springhibernate.model.note.NoteType</value>
            <value>ru.mightynoobs.springhibernate.model.note.Note</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/mightynoobsdb</prop>
            <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
        </props>
    </property>
</bean>

<!--UserDao and UserService beans-->
<bean id="userDao" class="ru.mightynoobs.springhibernate.dao.user.UserDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="userService" class="ru.mightynoobs.springhibernate.service.user.UserServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>

<!--NoteDao and NoteService beans-->
<bean id="noteDao" class="ru.mightynoobs.springhibernate.dao.note.NoteDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="noteService" class="ru.mightynoobs.springhibernate.service.note.NoteServiceImpl">
    <property name="noteDao" ref="noteDao"/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

When i did something like this:

private UserService userService = (UserService) SpringUtil.getBean("userService")

is works easily. Any suggestions, please?

回答1:

We use the normal @Inject annotations BUT we have this AbstractVM what we need to extend in order to let it work :

public abstract class AbstractVM {

    public AbstractVM() {
        this.autowire(this);
    }

    protected final void autowire(Object object) {
        this.getApplicationContext().getAutowireCapableBeanFactory()
                .autowireBean(object);
        this.getApplicationContext().getAutowireCapableBeanFactory()
                .initializeBean(object, null);
    }

    /**
     * Gets the application context.
     *
     * @return the application context
     */
    protected final ApplicationContext getApplicationContext() {
        return WebApplicationContextUtils
                .getRequiredWebApplicationContext(Executions.getCurrent()
                        .getDesktop().getWebApp().getServletContext());
    }
}

so example of a vm :

import javax.inject.Inject;
public class OverviewVM extends AbstractVM {

    @Inject
    private NotaService notaService;
    @Inject
    private ContactService contactService;

Edit:

@Dunni is correct with his comment.
You can't use the autowired beans in the constructor. Mine previous solution was MVVM, but for MVC you need to put that code not in the constructor but in the doBeforeCompose or the doAfterCompose method. (override it from the SelectorComposer)



回答2:

Currently I'm using @variableResolver and it's working just fine.

Try this, remove your service and dao beans in your applicationContext.xml change your userDaoImpl and userServiceImpl class into :

userDaoImpl

@Repository
public class UserDaoImpl implements UserDao{

 @Autowired
 private SessionFactory sessionFactory;

}

userServiceImpl

@Service(value="userService")
@Transactional
public class UserServiceImpl implements UserService{

 @Autowired
 private UserDao userDao;
}

and make sure your component-scan path into correct dao and service package

<context:component-scan base-package="ru.mightynoobs.springhibernate"/>