spring 3.0

35
Spring Core Scott

Upload: scott-su

Post on 13-Jul-2015

378 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Spring 3.0

Spring Core

Scott

Page 2: Spring 3.0

• Inversion Of Control (IoC)• Aspect-Oriented Programming (AOP)• Testing

Page 3: Spring 3.0

Inversion Of Control (IoC)

A

B C

Page 4: Spring 3.0

A

B C

IoC

Page 5: Spring 3.0

如何設定bean?

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {public Account loadAccount(Long accountId) {

Account account = dao.findAccount(accountId);return account;

}}

Page 6: Spring 3.0

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-

context-3.2.xsd">

<bean id="accountService" class="com.gorilla.netstream.user.service.impl.AccountServiceImpl" ></bean>

</beans>

Page 7: Spring 3.0

Naming Rule

Ex: loginController, accountService, userDao

Page 8: Spring 3.0

Dependency Injection

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {private AccountDao dao;public Account loadAccount(Long accountId) {

Account account = dao.findAccount(accountId);return account;

}}

package com.gorilla.netstream.user.dao.implpublic class AccountDaoImpl implements AccountDao {

public Account findAccount(Long accountId) {…return account;

}}

Page 9: Spring 3.0

Dependency Injection: Constructor-Based

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {private AccountDao dao;

public AccountServiceImpl(AccountDao dao) {this.dao = dao;

}

public Account loadAccount(Long accountId) {Account account = dao.findAccount(accountId);return account;

}}

Page 10: Spring 3.0

<beans …>

<bean id="accountService" class="com.gorilla.netstream.user.service.impl.AccountServiceImpl" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountDao" class="com.gorilla.netstream.user.dao.impl.AccountDaoImpl" />

</beans>

Page 11: Spring 3.0

Dependency Injection: Setter-Based

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {private AccountDao dao;

public void setDao(AccountDao dao) {this.dao = dao;

}

public Account loadAccount(Long accountId) {Account account = dao.findAccount(accountId);return account;

}}

Page 12: Spring 3.0

<beans …>

<bean id="accountService" class="com.gorilla.netstream.user.service.impl.AccountServiceImpl" ><property name="dao" ref= “accountDao" /><!--<property name="dao" >

<ref bean="accountDao" /></property>-->

</bean>

<bean id="accountDao" class="com.gorilla.netstream.user.dao.impl.AccountDaoImpl" />

</beans>

Page 13: Spring 3.0

Bean Scopes – Singleton

<bean id="accountService1" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountService2" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountService3" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountDao" class="…" />

1.

Page 14: Spring 3.0

Bean Scopes – Prototype

<bean id="accountService1" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountService2" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountService3" class="…" ><constructor-arg ref="accountDao" />

</bean>

<bean id="accountDao" class="…" />

1.

2.

3.

Page 15: Spring 3.0

Bean Scopes

• Singleton: 每一個Spring Container會共用同一個Bean Instance。(default)

• Prototype: 每一次Request都會建立一個新的Instance來服務。

• Request: 每一次HTTP Request都共用同一個Bean Instance。

• Session: 每一個HTTP Request都共用同一個Bean Instance。

• Global Session: 每一個Global HTTP Request都共用同一個Bean Instance。(Portlet only)

Page 16: Spring 3.0

Annotation-based

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context=http://www.springframework.org/schema/contextxsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config />

</beans>

Page 17: Spring 3.0

@Required

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {private AccountDao dao;

@Requiredpublic void setDao(AccountDao dao) {

this.dao = dao;}

public Account loadAccount(Long accountId) {Account account = dao.findAccount(accountId);return account;

}}

Page 18: Spring 3.0

@Autowired

package com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao dao;

@Autowiredpublic void setDao(AccountDao dao) {

this.dao = dao;}

@Autowiredpublic AccountServiceImpl(AccountDao dao) {

this.dao = dao;}

}

擇一使用

Page 19: Spring 3.0

@Qualifierpackage com.gorilla.netstream.user.service.impl

public class AccountServiceImpl implements AccountService {

@Autowired@Qualifier("accountDao")private AccountDao accountDao;

}

Page 20: Spring 3.0

支援JSR-250• @Resource• @PostConstruct• @PreDestory

支援JSR-330• @Inject• @Qualifier• @Named• @Provider

Page 21: Spring 3.0

@Autowired v.s. @Resource

Page 22: Spring 3.0

Classpath scanning

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context=http://www.springframework.org/schema/contextxsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.gorilla.netstream.*.service" />

</beans>

Page 23: Spring 3.0

• @Component• @Repository• @Service• @Controller

Page 24: Spring 3.0

Aspect-Oriented Programming (AOP)

横切的關注點

Page 25: Spring 3.0

CourseService

StudentService

MiscService

Security

Log

Transactio

n

Oth

er

Page 26: Spring 3.0

AOP術語

• 切面(Aspect):一個關注點的模組化,這個關注點可能會橫切多個物件。

• 連接點(Joinpoint):在程序執行過程中某個特定的點,比如某方法調用的時候或者處理異常的時候。

• 通知(Advice):在Aspect的某個特定的連接點上執行的動作。• 切入點(Pointcut):用於指定某Aspect在某Joinpoint中織入到應用程序之上。

• 引入(Introduction):用來給一個型別宣告額外的方法或屬性。• 目標物件(Target Object):一個Advice被應用的目標物件。• AOP代理(AOP Proxy):AOP框架創建的物件,用來實作切面契約(例如通知方法執行等等)。

• 織入(Weaving):把Aspect應用到Target上的過程。

Page 27: Spring 3.0
Page 28: Spring 3.0

<beans …><aop:aspectj-autoproxy expose-proxy="true" /></beans>

Page 29: Spring 3.0

@Aspect@Componentpublic class ExcuteLogAspect {

public final static Logger log = Logger.getLogger("System");

@Pointcut("execution(* com.gorilla.netstream.*.service.impl.*.*(..))")public void inService() {}

@Pointcut("execution(* com.gorilla.netstream.*.dao.impl.*.*(..))")public void inDao() {}

@Before("inService() || inDao()")public void before(JoinPoint jp) {

log.info("Calling " + jp.getSignature().getDeclaringType().getSimpleName() + "." + jp.getSignature().getName() + ".");

}

@Around("inService() || inDao()")public Object around(ProceedingJoinPoint pjp) throws Throwable {

long start = System.currentTimeMillis();Object output = pjp.proceed();long end = System.currentTimeMillis();long elapsedTime = end - start;log.info(pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " milliseconds.");return output;

}

@AfterThrowing(pointcut="inService() || inDao()", throwing="ex")public void afterThrowing(JoinPoint jp,Throwable ex) {

log.info(jp.getSignature().toShortString() + " throw exception.", ex);}

}

Page 30: Spring 3.0

@Aspect@Componentpublic class ExcuteLogAspect {

…}

@Pointcut("execution(* com.gorilla.netstream.*.service.impl.*.*(..))")public void inService() {}

@Before("inService() || inDao()")public void before(JoinPoint jp) {

log.info("Calling " + jp.getSignature().getDeclaringType().getSimpleName() + "." + jp.getSignature().getName() + ".");}

@Around("inService() || inDao()")public void before(JoinPoint jp) {

long start = System.currentTimeMillis();Object output = pjp.proceed();long end = System.currentTimeMillis();long elapsedTime = end - start;log.info(pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " milliseconds.");return output;

}

Page 31: Spring 3.0

• @Before• @AfterReturning• @AfterThrowing• @Around• @After

Page 32: Spring 3.0

Testing

package test.gorilla.netstream.user.service

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"classpath:/conf/spring/application-*.xml"})public class AccountServiceTest {

@Resourceprivate AccountService accountService;

@Testpublic void test() {

…}

}

Page 33: Spring 3.0

package test.gorilla.netstream.user.service

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations={"classpath:/conf/spring/application-*.xml"})public class AccountServiceTest {…}

package test.gorilla.netstream.user.service

@RunWith(SpringJUnit4ClassRunner.class)// classpath:/test/gorilla/netstream/user/service/AccountServiceTest-context.xml@ContextConfigurationpublic class AccountServiceTest {…}

package test.gorilla.netstream.user.service

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes={AppConfig.class, TestConfig.class})public class AccountServiceTest {…}

Page 34: Spring 3.0

Testing Annotation

http://docs.spring.io/spring/docs/3.2.10.RELEASE/spring-framework-reference/htmlsingle/#integration-testing-annotations

Page 35: Spring 3.0

Q & A