How to use spring 3.X annotation without any .xml configuration

一笑奈何 提交于 2019-12-24 03:07:43

问题


I'm new to Spring and I don't like to use .xml as the spring configuration. So I want to use only annotation. Following is my test code, it works well without spring, but if I use DI and add annotation "@Resource", I get NullPointException, could anyone help with it, thanks a lot.

I have imported related jar of spring already. It's a producer-consumer case, and I want to inject the resource-pool to producer and consumer.

Producer.java

import javax.annotation.Resource;

public class Producer implements Runnable{
    @Resource
    private ResourcePool qs;

    @Override
    public void run() {
        while (true) {
            for(int i = 0;i < Integer.MAX_VALUE; i++) {
                try {
                    qs.produce(i);
                    System.out.println("Add index = " + i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Consumer.java

import javax.annotation.Resource;

public class Consumer implements Runnable {
    @Resource
    private ResourcePool qs;

    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println("Remove index = " + qs.comsume());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

ResourcePool.java

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ResourcePool {
    private BlockingQueue<Integer> aBlockingQueue  = new ArrayBlockingQueue<Integer>(11);

    public void produce(Integer ins) throws InterruptedException{
        aBlockingQueue.put(ins);
    }

    public int comsume() throws InterruptedException{
        return aBlockingQueue.take();
    }
}

The main function

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPC {
    public static void main(String[] args){
        ExecutorService aExecutor = Executors.newFixedThreadPool(2);

        Producer productor = new Producer();
        Consumer consumer = new Consumer();
        aExecutor.execute(productor);
        aExecutor.execute(consumer);
    }
}

Exception message:

Exception in thread "pool-1-thread-2" java.lang.NullPointerException at testbq.Consumer.run(Consumer.java:14) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Exception in thread "pool-1-thread-1" java.lang.NullPointerException at testbq.Producer.run(Producer.java:14) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Thanks


回答1:


On searching "XML-less Spring configuration" or Java-based Spring configuration you should have probably figured it out yourself within a couple of minutes.

You haven't defined any bean-creatiion method which is hosted by a class that is annotated with @Configuration - so Spring is able to know what you actually want to inject.

@Configuration
// optional @ComponentScan(basePackages = {"name.your.package.here"}
public class AppConfig
{
    @Bean // or @Bean(name = "nameOfYourBean")
    public ResourcePool getResourcePool() 
    { 
        return new ResourcePool(); 
    }
}

Within your main method you should then create a Spring context and load your AppConfig in to your context:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfic.class);

HTH




回答2:


You can't use new Producer() because it will create a new Producer and not use spring at all. You need to load the application context as an annotation context and load Producer from the context:

public class TestPC {
    public static void main(String[] args){
         ExecutorService aExecutor = Executors.newFixedThreadPool(2);

         ApplicationContext ctx = 
             new AnnotationConfigApplicationContext("your.package.com"); 

         Producer producer = ctx.getBean(Producer.class);
         Consumer consumer = ctx.getBean(Consumer.class);
         aExecutor.execute(productor);
         aExecutor.execute(consumer);
   }
}

You have to replace your.package.com with the base package where Producer and Consumer classes reside.



来源:https://stackoverflow.com/questions/21059171/how-to-use-spring-3-x-annotation-without-any-xml-configuration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!