bom, uma das maiores criticas ao spring framework, é a quantidade excessiva de XML utilizados, bom, as ultimas versɵes do framework, suportam annotations para diversos tipos de configuração, o que é mais propagandeado é a parte de configuração de transações por annotations, mas a parte que eu mais gostei é a que substitui totalmente a configuração e mapeamento de controllers para a parte web, isto quer dizer que nÉ£o é necessária nem uma linha de configuração para adicionar um novo controller na aplicação.
Por enquanto, o Spring nÉ£o suporta as anotações do JDK 1.5, utiliza apenas o commons-annotations, o que requer um passo extra na compilação da aplicação.
bom, mas chega de papo furado, parece que é fácil demais né? bom, vamos a um pequeno exemplo:
/**
* @author Rodrigo Urubatan Ferreira Jardim
* @@org.springframework.web.servlet.handler.metadata.PathMap("/home.html")
*/
public class HomeController extends AbstractController {
private WorkFlowDao workFlowDao;
public void setWorkFlowDao(WorkFlowDao workFlowDao) {
this.workFlowDao = workFlowDao;
}
protected ModelAndView handleRequestInternal ( HttpServletRequest request, HttpServletResponse response ) throws Exception {
Collection processos = workFlowDao.listaProcessos();
return new ModelAndView("home","processos",processos);
}
}
bom, este controller extremamente complexo, precisa apenas ser compilado, e indexado pelo compilador do commons-attributes que vai atender pela URL "home.html" (sim, eu costumo utilizar a extensÉ£o HTML para as minhas páginas dinÉ¢micas também)
o que determina isto, é apenas aquele comentário em negrito na declaração da classe.
vamos ver como é feita a mágica, é necessária uma pequena alteração no build.xml, e a definição de alguns beans em um XML utilizado pelo spring (eu costumo utilizar applicationContext.xml, ou entÉ£o o proprio <servletname>-servlet.xml, que sera lido automáticamente pelo servlet do spring
vamos ao build.xml:
<target name="init">
<taskdef classpathref="project.class.path" resource="org/apache/commons/attributes/anttasks.properties" />
</target>
<target name="compile" depends="attrib">
<javac classpathref="project.class.path" destdir="${web.bin}" srcdir="${src.dir}" />
<javac classpathref="project.class.path" destdir="${web.bin}" srcdir="${src.temp}" />
</target>
<target name="attrib" depends="init">
<attribute-compiler destdir="${src.temp}">
<fileset dir="${src.dir}" includes="**/*.java" />
</attribute-compiler>
</target>
<target name="all" depends="compile,attrib">
<jar destfile="${web.lib}/${jar.name}" basedir="${web.bin}" compress="true" index="true">
<include name="**/*.*" />
</jar>
<attribute-indexer jarFile="${web.lib}/${jar.name}">
<classpath refid="project.class.path" />
</attribute-indexer>
</target>
o pulo do gato neste build.xml é a task: attribute-indexer que permite que o spring encontre os controller automáticamente
e as configurações necessárias no spring:
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" singleton="true">
<property name="customTargetSourceCreators">
<list>
<ref local="poolingTargetSourceCreator" />
</list>
</property>
</bean>
<bean id="transactionAttributeSource"
class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource"
autowire="constructor" singleton="true">
</bean>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor"
autowire="byType" singleton="true">
</bean>
<bean id="transactionAdvisor"
class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
autowire="constructor" singleton="true">
</bean>
<bean id="attributes"
class="org.springframework.metadata.commons.CommonsAttributes" singleton="true"/>
<bean id="poolingTargetSourceCreator"
class="org.springframework.aop.framework.autoproxy.metadata.AttributesPoolingTargetSourceCreator"
autowire="constructor" singleton="true">
</bean>
<bean id="commonsAttributesHandlerMapping" class="org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping" singleton="true"/>
aqui, todos estes beans colaboram de alguma forma, o default-autowire do contexto esta setado para: byName, isto quer dizer que se algum dos nomes for alterado, a cosia pode parar de funcionar, mas deixando assim ta tudo beleza
quem carrega os controller aqui, é o ultimo bean definido: commonsAttributesHandlerMapping
bom, o negócio parece show de bola, mas tem um probleminha na versÉ£o atual do spring (1.1), os controllers sÉ£o carregados sempre utilizando auto wire by bype, isto quer dizer que só pode existir um bean de cada tipo no contexto, mas eu fiz uma pequena alteração e mandei para o pessoal do spring, e o Rod Johnson respondeu dizendo que iria incluir a alteração para a versÉ£o 1.1.3 corrigindo este problema. Atualmente to utilizando a minha versÉ£o alterada com autoWireByName, acho bem mais flexivel
bom, eu achei super legal este suporte para anotações, acho que vcs podem aproveitar também, qualquer duvida postem aqui nos comentários.
Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!
Tags: historico, Java, Spring Framework