继承自接口的spring injection bean

时间:2017-06-18 09:33:05

标签: java spring

我有一些@Bean注释的配置,它的工作原理。 但是,如果我将bean更改为继承接口,那么它就不起作用了。我需要特殊的注释吗?

不带导入的配置类片段

@Configuration
@ComponentScan("io.github.aaa4")
//@ComponentScan({ "io.github.aaa4.dao", "io.github.aaa4.entity","io.github.aaa4.Servlets"})
@EnableTransactionManagement
public class AppConfig {

    @Bean
    public ComboPooledDataSource myDataSource() throws PropertyVetoException {
        ComboPooledDataSource ds = new ComboPooledDataSource();

        ds.setDriverClass("com.mysql.jdbc.Driver");
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/emp?useSSL=false");
        ds.setUser("emp");
        ds.setPassword("emp");
        ds.setMinPoolSize(2);
        ds.setMaxPoolSize(20);
        ds.setMaxIdleTime(30000);

        return ds;
    }

    @Bean
    public LocalSessionFactoryBean mySessionFactory() throws PropertyVetoException {
        LocalSessionFactoryBean sf = new LocalSessionFactoryBean();
        Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        hibernateProperties.setProperty("hibernate.show_sql", "true");

        sf.setDataSource(myDataSource());
        sf.setPackagesToScan("io.github");
        sf.setHibernateProperties(hibernateProperties);

        return sf;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager myTransactionManager(SessionFactory sessionFactory) {
        HibernateTransactionManager htm = new HibernateTransactionManager();
        htm.setSessionFactory(sessionFactory);

        return htm;
    }


    @Bean
    public UserDao userDaoImpl() {
        return new UserDaoImpl();
    }

    @Bean
    public DBService dBServiceImpl() {
        return new DBServiceImpl();
    }

}

serviceImpl片段

@Service
public class DBServiceImpl implements DBService {

    //inject user DAO
    @Autowired
    private UserDao userDao;

    @Transactional
    public void addUser(MyUser user) {
        userDao.createUser(user);
    }

    @Transactional
    public List<MyUser> getUserList() {
        return userDao.getusers();
    }

    @Transactional
    public void deleteUser(int theId) {
        userDao.deleteUser(theId);
    }


}

主要班级

public class Main {
 public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

        DBServiceImpl service = ctx.getBean(DBServiceImpl.class);

        MyUser user = new MyUser("alice", "and her passwd");
        System.out.println("this is the user:" + user);
        service.addUser(user);
        service.addUser(user);
        service.addUser(user);
        service.addUser(user);
        System.out.println("User added!");
        service.deleteUser(2);
        System.out.println("user number id = 2 deleted");
        List<MyUser> userList = service.getUserList();
        for (MyUser users : userList)
            System.out.println(users);
        ctx.close();
    }

}

有问题的堆栈跟踪

  INFO: Using DataSource [com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1hge1459o1fr6qmlst9469|42e99e4a, dataSourceName -> 1hge1459o1fr6qmlst9469|42e99e4a ]] of Hibernate SessionFactory for HibernateTransactionManager

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.github.aaa4.services.DBServiceImpl' available

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:353)

    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)

    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
    at io.github.aaa4.Main.main(Main.java:30)

在配置类之上注释@EnableAspectJAutoProxy(proxyTargetClass = true)

WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:223)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:702)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:527)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
    at io.github.aaa4.Main.main(Main.java:14)
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/annotation/Around
    at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.<clinit>(ReflectiveAspectJAdvisorFactory.java:77)
    at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(AnnotationAwareAspectJAutoProxyCreator.java:78)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.setBeanFactory(AbstractAdvisorAutoProxyCreator.java:60)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1647)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1615)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    ... 10 more
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Around
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 16 more

3 个答案:

答案 0 :(得分:1)

”要记住的重要一点是,如果事务Bean正在实现接口,则默认情况下,代理将是Java动态代理。这意味着将仅拦截通过代理传入的外部方法调用。 “

请参阅https://www.baeldung.com/transaction-configuration-with-jpa-and-spring

以下应使其起作用:

DBService服务= ctx.getBean(DBService.class);

答案 1 :(得分:0)

尝试使用接口而不是实现

datetimes = datetime(0,0,0,0,0,t); % convert seconds to datetime
plot(datetimes,y)
datetick('x', 'MM:SS'); % set the x tick format (Note that you should now use capital M and S in the format string
xlim([min(datetimes) max(datetimes)])

您的服务方法有DBService service = ctx.getBean(DBService.class); 个注释。应在启动时扫描所有@Transactional注释,并且目标方法应成为事务性的。要添加事务行为,Spring会为您的类创建一个代理。这就是为什么你不能得到你的豆。

答案 2 :(得分:0)

我认为,您应该在此行DBServiceImpl service = ctx.getBean(DBServiceImpl.class);中更改为DBService service = ctx.getBean(DBService.class);

用于参考检查弹簧文档Using the @Bean annotation Spring DOC