上一篇的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 的小寫開頭類名
※可以利用這個特性做多型
沒有留言:
張貼留言