SSH ALL-IN-ONE
很多新来的同事不了解我们的项目架构 准备补充一下我们的项目架构 Spring-Hibernate Based.
主要涉及到一下几个方面
Queue-based event processing
Producer: IDBSync
Consumer: EAI
for producer:
shell, bash, cron job,
for consumer:
hibernate to persistent
spring to glue business and others together, such as transaction,exception,Schedule,Mail,Webservice,apache cxf integration...
Others
Hudson, maven, profile for test,dev,stage,production...
Spring (IOC, DI)
container--factory--bean
<beans> <bean id="triangle" class="a.b.c.Triangle" /> </beans>
getbean from XmlBeanFactory
BeanFactory factory= new XmlBeanFactory(new FileSystemResource("spring.xml")); Triangle triangle = (Triangle)factory.getBean("triangle");
application context
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Triangle triangle =(Triangle)context.getBean("triangle");
Bean with property
<beans> <bean id="triangle" class="a.b.c.Triangle" > <property name="type" value="Equlateral"/> </bean> </beans>
Constructor injection
<beans> <bean id="triangle" class="a.b.c.Triangle" > <constructor-arg type="java.lang.String" index="0" value="Equlateral"/> <constructor-arg index="1" value="20" /> </bean> </beans>
injection object
<beans> <bean id="triangle" class="a.b.c.Triangle" > <property name="pointA" ref="aPoint"> </bean> <bean id="aPoint" class="a.b.c.Point" > <property name="x" value="20"> <property name="y" value="120"> </bean> </beans>
inner bean, aliases,idref
<beans> <bean id="triangle" class="a.b.c.Triangle" name="triangle-name"> <property name="pointA" ref="aPoint"> <property name="pointC"> < idref="Point0"/> </property> <property name="pointB"> <bean id="point2" class="a.b.c.Point" > <property name="x" value="19"> <property name="y" value="12"> </bean> </property> </bean> <bean id="aPoint" class="a.b.c.Point" > <property name="x" value="20"> <property name="y" value="120"> </bean> <bean id="Point0" class="a.b.c.Point" > <property name="x" value="0"> <property name="y" value="0"> </bean> <alias name="triangle" alias="triangle-alias" /> </beans>
Collections
<beans> <bean id="triangle" class="a.b.c.Triangle" > <property name="points" > <list> <ref bean="aPoint"> <ref bean="bPoint"> </list> </property> </bean> <bean id="aPoint" class="a.b.c.Point" > <property name="x" value="20"> <property name="y" value="120"> </bean> <bean id="bPoint" class="a.b.c.Point" > <property name="x" value="120"> <property name="y" value="1120"> </bean> </beans>
autowiring=byName,byType,constructor
<beans> <bean id="triangle" class="a.b.c.Triangle" autowire="byName"> </bean> <bean id="aPoint" class="a.b.c.Point" > <property name="x" value="20"> <property name="y" value="120"> </bean> <bean id="bPoint" class="a.b.c.Point" > <property name="x" value="120"> <property name="y" value="1120"> </bean> </beans>
Spring Bean Scope
- singleton - Only once per Spring container(default)
- prototype - new bean created with every request or reference
Web-aware context bean scope
- request - new bean per servlet request
- session - new bean per session
- global session - new bean per global http session(portlet context)
<beans> <bean id="bPoint" class="a.b.c.Point" scope="prototype"> <property name="x" value="120"> <property name="y" value="1120"> </bean> </beans>
Using applicationContextAware
public class Triangle implements ApplicationContextAware, BeanNameAware{ private ApplicationContext context=null; @override public void setApplicationContext(ApplicationContext context) throws BeansException{ this.context = context; } @override public void setBeanName(String beanName){ System.out.println("bean name is: " +beanName); } }
Lifecycle Callbacks
public class Triangle implements InitializingBean, DisposableBean{ @Override public void afterPropertiesSet() throws Exception{ } @Override public void destory() throws Exception{ } public void myInit(){ } public void myclean(){ } }
customize init-method and destory-method
<beans> <bean id="bPoint" class="a.b.c.Point" init-method="myInit" destory-method="myclean"> <property name="x" value="120"> <property name="y" value="1120"> </bean> </beans>
BeanPostProcessor
public class XXX implements BeanPostProcessor{ @Override public Object postProcessAfterInitialization(object bean,String beanName) throws BeansException{ return bean; } @Override public Object postProcessBeforeInitialization(object bean,String beanName) throws BeansException{ return bean; } }
Coding to interface
Annotation
Using MessageSource to get text from property files
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>mymessages</value> </list> </property> </bean>
mymessages.propeties
and in java
ApplicationContext context ; context.getMessage("key",null,"default value");
Event handing
ApplicationEventPublisher.publishEvent() + ApplicationEvent + ApplicationListener
built-in event:
- ContextRefreshedEvent
- ContextClosedEvent
- RequestHandleEvent : web app related, for DispatcherServlet
Load ApplicationContext in web application
ContextLoaderListerner in web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
or ContextLoaderServlet to, but prefer ContextLoaderListener
with Hibernate, Spring as a Container injects all hibernate's dependencies automatically.
SessionFactory+datasource+transactionManager
org.springframework.orm.hibernate3.LocalSessionFactoryBean
org.springframework.orm.hibernate3.HibernateTransactionManager
AOP
import org.aspectj.lang.annotation.Aspect; @Aspect public class LoggingAspect{ @Before("execution(public String getName())") public void loggingAdvice(){ System.out.println("Advice run, getName method called."); } }
config
<beans> <aop:aspectj-autoproxy /> <bean name=''loggingAspect" class="a.b.c.LoggingAspect"/> </beans>
or define a pointcut
@Aspect public class LoggingAspect{ @Before("allGetters()") public void loggingAdvice(){ System.out.println("Advice run, get* method called."); } @Pointcut("execution(* get*())") public void allGetters(){} }
Around pointcut
@Around("allGetters()") public Object myAroundAdvice(ProceedingJoinPoint joinPoint){ Object returnValue = null; try{ System.out.println("Before advice"); returnValue = joinPoint.proceed(); System.out.println("After Returning"); }catch(Throwable e){ System.out.println("After Throwing"); } System.out.println("After Finally"); return returnValue; }