上一篇的xml還是要宣告
@Component("bo") // Book.java
@Component("ca") // Cartoon.java
@Component("co") // Comic.java
※在三支vo的class上面增加如上的annotation
這時xml只要這兩行就可以了
<context:annotation-config /> <context:component-scan base-package="\" />
轉換個場景,一般在開發時都會有controller-->Service-->ServiceImpl-->DAO可以這樣定義
※XML設定
BookAction.java
public class BookAction {
private IBookService service;
public void setService(BookServiceImpl service) {
this.service = service;
}
public void go() {
service.get();
}
}
IBookService.java
public interface IBookService {
public void get();
}
BookServiceImpl.java
public class BookServiceImpl implements IBookService {
private BookDAOImpl dao;
public void setDao(BookDAOImpl dao) {
this.dao = dao;
}
public void get() {
dao.getBook();
}
}
BookDAOImpl.java
public class BookDAOImpl {
public void getBook() {
System.out.println("資料庫操作");
}
}
applicationContext.xml
<bean id="bookAction" class="controller.BookAction" p:service-ref="bookServiceImpl" /> <bean id="bookServiceImpl" class="serviceImpl.BookServiceImpl" p:dao-ref="bookDAOImpl" /> <bean id="bookDAOImpl" class="dao.BookDAOImpl" />
測試類
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationContext.xml");
BookAction c = (BookAction) ctx2.getBean("bookAction");
c.go();
((ClassPathXmlApplicationContext) ctx2).close();
結果:
資料庫操作
※Annotation設定
BookAction.java
package controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import service.IBookService;
import serviceImpl.BookServiceImpl;
@Controller
public class BookAction {
// @Resource
@Autowired
private IBookService service;
public void setService(BookServiceImpl service) {
this.service = service;
}
public void go() {
service.get();
}
}
BookServiceImpl.java
package serviceImpl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import dao.BookDAOImpl;
import service.IBookService;
@Service
public class BookServiceImpl implements IBookService {
// @Autowired
@Resource
private BookDAOImpl dao;
public void setDao(BookDAOImpl dao) {
this.dao = dao;
}
public void get() {
dao.getBook();
}
}
BookDAOImpl.java
@Repository
public class BookDAOImpl {
public void getBook() {
System.out.println("資料庫操作");
}
}
applicationContext.xml
<context:annotation-config /> <context:component-scan base-package="\" />
測試類
ApplicationContext ctx1 = new AnnotationConfigApplicationContext("applicationContext.xml");
System.out.println(ctx1.getBeanDefinitionCount());
for (String s : ctx1.getBeanDefinitionNames()) {
System.out.println(s);
}
((AnnotationConfigApplicationContext) ctx1).close();
System.out.println("----------------------------------------");
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ctx2.getBeanDefinitionCount());
for (String s : ctx2.getBeanDefinitionNames()) {
System.out.println(s);
}
IBookService service1 = ctx2.getBean("bookServiceImpl", IBookService.class);
BookServiceImpl service2 = (BookServiceImpl) ctx2.getBean("bookServiceImpl");
service1.get();
service2.get();
BookAction c = (BookAction) ctx2.getBean("bookAction");
c.go();
((ClassPathXmlApplicationContext) ctx2).close();
System.out.println("----------------------------------------");
ApplicationContext ctx3 = new AnnotationConfigApplicationContext(BookAction.class, BookServiceImpl.class,
BookDAOImpl.class);
System.out.println(ctx3.getBeanDefinitionCount());
for (String s : ctx3.getBeanDefinitionNames()) {
System.out.println(s);
}
IBookService service3 = ctx3.getBean("bookServiceImpl", BookServiceImpl.class);
BookServiceImpl service4 = (BookServiceImpl) ctx3.getBean("bookServiceImpl");
service3.get();
service4.get();
BookAction controller = (BookAction) ctx3.getBean("bookAction");
controller.go();
((AnnotationConfigApplicationContext) ctx3).close();
※結果:
5
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
-------------------------------------------------------------------------
8
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
bookAction
bookDAOImpl
bookServiceImpl
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
資料庫操作
資料庫操作
資料庫操作
-------------------------------------------------------------------------
8
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
資料庫操作
資料庫操作
資料庫操作
※service.java什麼註解都不用,和xml設定的一樣,註了也沒什麼效果
※@Controller、@Service、@Repository這三個annotation裡面都包括@Component,所以也可以用@Component代替,經測試過這四個annotation可以隨便使用,不過最好是按照它的名稱來使用會比較直覺
@Controller:就放在controller上
@Service:就放在service上
@Repository:就放在DAO上
而預設的id名稱就是class名稱,然後第一個字改小寫,所以上面的controller也等於@Controller("bookAction"),測試類在拿來用即可
※上面還有@Resource和@Autowired,有這兩個其中之一,setter可以不寫,會自動塞值
如果沒有這兩個annotation,service和dao會是null,所以在「.」就會NullPointException,不想用annotation的話只能new了-->private BookDAOImpl dao = new BookDAOImpl();
※getBeanDefinitionCount方法可以取得所有的bean數目,預設有5筆; getBeanDefinitionNames方法可以取得所有的bean名稱
※測試類一共有三種取bean的方式,ctx1是不行的,因為bean數目是預設的5筆
※這次的專案內容路徑
※@Scope
和之前的xml設定一樣,可以控制要不要同一個實體BookAction.java
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Controller
public class BookAction {}
applicationContext.xml
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationContext.xml");
BookAction s1 = (BookAction) ctx2.getBean("bookAction");
System.out.println(s1);
BookAction s2 = (BookAction) ctx2.getBean("bookAction");
System.out.println(s2);
((ClassPathXmlApplicationContext) ctx2).close();
※JSR330 的 Annotation
參考資料Spring javax.inject.*
@Autowired @Inject
@Component @Named
@Scope("singleton") @Singleton
@Qualifier @Named
@Value 無
@Required 無
@Lazy 無
※連結往上一點,就會看到有maven的jar可以複製,我覺得這張表已經很清楚了,我沒有全試,不過run起來還蠻順的,要注意@Named可以用在兩個地方
※自動裝配 Map、List
package xxx;
public interface IspeakService {
void speak();
}
package xxx;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@ComponentScan("xxx")
@Component
public class Bird implements IspeakService {
public void speak() {
System.out.println("吱吱吱");
}
}
package xxx;
import org.springframework.stereotype.Component;
@Component
public class Lion implements IspeakService {
public void speak() {
System.out.println("吼吼吼");
}
}
※一個介面多個實作
package xxx;
import xxx.Bird;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Bird.class)
public class TestSomething {
@Resource
public Map<String, IspeakService> mapService;
@Resource
public List<IspeakService> listService;
@Test
public void testXxx() {
System.out.println(mapService);
listService.forEach(x -> System.out.println(x.getClass()));
}
}
※直接使用 @Autowired 或 @Resource 就可以直接抓到了
※Map 的 key 值是 @Component 的小寫開頭類名
※可以利用這個特性做多型

沒有留言:
張貼留言