2015年12月31日 星期四

基於 Java container 的設定 (Spring3.x 十四)

參考文件
基於 Java container的annotation最主要就是@Configuration和@Bean



※@Configuration和@Bean

BookAction.java

@Configuration
public class BookAction {
    @Inject
    private IBookService service;
    
    @Bean(name = "og")
    public String go() {
        return service.get();
    }
}



IBookService.java和BookServiceImpl.java

public interface IBookService {
    public String get();
}
    
@Named
public class BookServiceImpl implements IBookService {
    @Inject
    private BookDAOImpl dao;
    
    public String get() {
        return dao.getBook();
    }
}



BookDAOImpl.java

@Component
public class BookDAOImpl {
    public String getBook() {
        return "資料庫操作";
    }
}



測試類

ApplicationContext ctx3 = new AnnotationConfigApplicationContext(BookAction.class, BookServiceImpl.class, BookDAOImpl.class);
    
System.out.println(ctx3.getBeanDefinitionCount());
for (String s : ctx3.getBeanDefinitionNames()) {
    System.out.println(s);
}
System.out.println("----------------------------------------");
    
// BookAction controller = (BookAction) ctx3.getBean("bookAction");
BookAction controller = ctx3.getBean(BookAction.class);
System.out.println(controller.go());
    
((AnnotationConfigApplicationContext) ctx3).close();

※結果:
9
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
bookAction
bookServiceImpl
bookDAOImpl
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
og
----------------------------------------
資料庫操作

※如果只設定@Bean,那id就是方法名稱

※@Bean不能在回傳值是void上面,否則會出「needs to have a non-void return type!」的錯

※@Named、@Component、@Controller、@Service、@Repository、@Configuration可混用

※@Autowired、@Resource、@Inject可混用

※測試類的BookAction那兩行都可以,本來是呼叫id,也還是可以用,現在變成呼叫class

※還可以這樣使用:
AnnotationConfigApplicationContext ctx3 = new AnnotationConfigApplicationContext();
ctx3.register(BookAction.class, BookServiceImpl.class);
ctx3.register(BookDAOImpl.class);
// ctx3.scan("\\");
ctx3.refresh();

※scan()等同xml設定的<context:component-scan base-package="\" />



※@Bean的初始銷毀方法


BookAction.java

@Configuration
public class BookAction {
    @Inject
    @Named("bookServiceImpl")
    private IBookService service;
    
    @Bean(name = "og", initMethod = "ooo", destroyMethod = "xxx")
    public IBookService go() {
        return service.get();
    }
}



IBookService.java和BookServiceImpl.java

public interface IBookService {
    public IBookService get();
}
    
@Named
public class BookServiceImpl implements IBookService {
    @Inject
    private BookDAOImpl dao;
    
    public void ooo() {
        System.out.println("ooo");
    }
    
    public void xxx() {
        System.out.println("xxx");
    }
    
    public IBookService get() {
        return this;
    }
}

※@Named("bookServiceImpl")是因為會出「 org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [service.IBookService] is defined: expected single matching bean but found 2: bookServiceImpl,og」的錯,有兩個id的型態都是IBookService,所以才加這行,@Named就是這兩種用法,就是上一篇介紹的連結,有一張表寫的很清楚

※initMethod 和 destroyMethod 要寫在回傳值的class裡面才行,但我試過回傳null就不會執行了(但也不會出錯),所以一定真的有到class裡面才行,就算是new個空的也會抓到


沒有留言:

張貼留言