Spring ioc-advanced
Upcoming SlideShare
Loading in...5
×
 

Spring ioc-advanced

on

  • 945 views

 

Statistics

Views

Total Views
945
Views on SlideShare
945
Embed Views
0

Actions

Likes
0
Downloads
18
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Spring ioc-advanced Spring ioc-advanced Presentation Transcript

  • Spring frameworkMotto: Musíte rozbít vejce když chcete udělat omeletuSpring framework training materials by Roman Pichlík is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.Tuesday 28 May 13
  • IoC containerAdvancedTuesday 28 May 13
  • Agenda• Hierarchická konfigurace• Dynamické nahrávání kontextů• PropertyEditory• Validace• SPELTuesday 28 May 13
  • Konfigurace na druhouTuesday 28 May 13
  • PropertiesTuesday 28 May 13
  • Property placeholders• Konfigurace mimo XML• Atributy spjaté s prostředím• databáze, HTTP endpointy atd.• známe až v deploy timeTuesday 28 May 13- Operations opravdu neradi editují XML v zanorenem JARu na filesystemu
  • Příklad@Componentpublic class MyAnnotatedBean { @Value("${username}") private String username; public String getUsername() { return username; }}Tuesday 28 May 13
  • Složitější případ užití• Proč jeden soubor nestačí• různá prostředí• testy, produkce, developer stroj• chceme definovat smart defaultsTuesday 28 May 13
  • Konfigurační hierarchie• Každá komponenta můžedefinovat default hodnoty• Aplikace definuje svojedefault hodnoty• Prostředí definuje svojehodnotyComponent defaultsApplication defaultsEnvironment valuespřepisujeTuesday 28 May 13System.properties override
  • Provedení• Pořadí definice určuje prioritu• Dynamické načítání zclasspath• Chybějící properties souboryse ignorují• přenositelnost<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="ignoreResourceNotFound" value="true" /><property name="ignoreUnresolvablePlaceholders" value="true" /><property name="locations"><list><value>classpath*:META-INF/componentDefault.properties</value><value>classpath:META-INF/applicationDefault.properties</value><value>file:/opt/configuration/deployment.properties</value></list></property></bean>Tuesday 28 May 13
  • Resource abstrakceTuesday 28 May 13
  • Resource• Spring abstrakce pro přístup ksouborům v různém prostředíPrefix Příklad Vysvětlivkaclasspath: classpath:com/myapp/config.xml Nahravá se z classpathfile: file:/data/config.xml Nahrává se z FShttp: http://myserver/logo.png Nahrává přes URLBez prefixu /data/config.xml Závisí na typu ApplicationContextResource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");<bean id="myBean" class="..."><property name="template" value="some/resource/path/myTemplate.txt"/></bean>Tuesday 28 May 13
  • Wildcards & Ant path/WEB-INF/*-context.xmlclasspath:com/mycompany/**/applicationContext.xmlclasspath*:META-INF/*-beans.xml• Wildcard *• nahrání více resourců• komplexní boot aplikaceTuesday 28 May 13
  • Dynamické sestavení kontextuTuesday 28 May 13
  • Motivace• Pouze ze začátku vystačí jedenbean definition file na aplikace• nepraktické• chceme oddělit definici beanpodle komponenty nebo typu• přehlednostTuesday 28 May 13
  • Využití Resource abstrakce• Definujte kontexty v předemdefinované cestě• META-INF/company/spring• Pojmenované s pevným suffixem• *-applicationContext.xmlTuesday 28 May 13
  • Inicializace• Automatické načtení všechbean definic na classpath• usnadňuje přidávánínových kontextů• umožňuje dynamickénačítání podle toho jak jeclasspath sestavena• někdy méně přehlednéString path ="classpath*:META-INF/company/*-applicationContext.xml";new ClassPathXmlApplicationContext(path);<context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:META-INF/company/*-applicationContext.xml</param-value></context-param>Tuesday 28 May 13
  • Strategický context• Definuje infrastrukturní beanypoužívané v celé aplikaci• DataSource, Transakční manažer,HibernateSessionFactory atd.• Může mít různou podobu prorůzná prostředí• Testy, Produkce, Aplikační serverTuesday 28 May 13- nejdulezitejsi beany na jednom miste- lze pouzit import
  • PropertyEditorsTuesday 28 May 13
  • java.beans.PropertyEditor• Rozhraní pro konverzi String –>Datový typ ve Springu• Používá se• inicializace kontejneru anastavování bean values• Spring MVC konverze z queryparams (?name=dagi&age=31)Tuesday 28 May 13
  • public class BeanWithSpecialDate {private SpecialDateType specialDateType;public SpecialDateType getSpecialDateType() {return specialDateType;}public void setSpecialDateType(SpecialDateType specialDateType) {this.specialDateType = specialDateType;}}public class SpecialDateType {private final Date date;public SpecialDateType(Date date) {this.date = date;}public Date getDate() {return date;}}public class SpecialDatePropertyEditor extends PropertyEditorSupport{@Overridepublic void setAsText(String text) throws IllegalArgumentException {SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");try {setValue(new SpecialDateType(sdf.parse(text)));} catch (ParseException e) {throw new IllegalArgumentException("Cannot parse date", e);}}}<bean class="cz.sweb.pichlik.springioc.propertyeditor.BeanWithSpecialDate"><property name="specialDateType" value="01-01-2000" /></bean><bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entrykey="cz.sweb.pichlik.springioc.propertyeditor.SpecialDateType"value="cz.sweb.pichlik.springioc.propertyeditor.SpecialDatePropertyEditor"/></map></property></bean>je definovanásespeciálnímtypemuvedeným jako StringTuesday 28 May 13
  • public class BeanWithSpecialDate {private SpecialDateType specialDateType;public SpecialDateType getSpecialDateType() {return specialDateType;}public void setSpecialDateType(SpecialDateType specialDateType) {this.specialDateType = specialDateType;}}public class SpecialDateType {private final Date date;public SpecialDateType(Date date) {this.date = date;}public Date getDate() {return date;}}public class SpecialDatePropertyEditor extends PropertyEditorSupport{@Overridepublic void setAsText(String text) throws IllegalArgumentException {SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");try {setValue(new SpecialDateType(sdf.parse(text)));} catch (ParseException e) {throw new IllegalArgumentException("Cannot parse date", e);}}}<bean class="cz.sweb.pichlik.springioc.propertyeditor.BeanWithSpecialDate"><property name="specialDateType" value="01-01-2000" /></bean><bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entrykey="cz.sweb.pichlik.springioc.propertyeditor.SpecialDateType"value="cz.sweb.pichlik.springioc.propertyeditor.SpecialDatePropertyEditor"/></map></property></bean>o jehož konverzi se stará PropertyEditorTuesday 28 May 13
  • public class BeanWithSpecialDate {private SpecialDateType specialDateType;public SpecialDateType getSpecialDateType() {return specialDateType;}public void setSpecialDateType(SpecialDateType specialDateType) {this.specialDateType = specialDateType;}}public class SpecialDateType {private final Date date;public SpecialDateType(Date date) {this.date = date;}public Date getDate() {return date;}}public class SpecialDatePropertyEditor extends PropertyEditorSupport{@Overridepublic void setAsText(String text) throws IllegalArgumentException {SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");try {setValue(new SpecialDateType(sdf.parse(text)));} catch (ParseException e) {throw new IllegalArgumentException("Cannot parse date", e);}}}<bean class="cz.sweb.pichlik.springioc.propertyeditor.BeanWithSpecialDate"><property name="specialDateType" value="01-01-2000" /></bean><bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entrykey="cz.sweb.pichlik.springioc.propertyeditor.SpecialDateType"value="cz.sweb.pichlik.springioc.propertyeditor.SpecialDatePropertyEditor"/></map></property></bean>patřičně zaregistrovanýTuesday 28 May 13
  • public class BeanWithSpecialDate {private SpecialDateType specialDateType;public SpecialDateType getSpecialDateType() {return specialDateType;}public void setSpecialDateType(SpecialDateType specialDateType) {this.specialDateType = specialDateType;}}public class SpecialDateType {private final Date date;public SpecialDateType(Date date) {this.date = date;}public Date getDate() {return date;}}public class SpecialDatePropertyEditor extends PropertyEditorSupport{@Overridepublic void setAsText(String text) throws IllegalArgumentException {SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");try {setValue(new SpecialDateType(sdf.parse(text)));} catch (ParseException e) {throw new IllegalArgumentException("Cannot parse date", e);}}}<bean class="cz.sweb.pichlik.springioc.propertyeditor.BeanWithSpecialDate"><property name="specialDateType" value="01-01-2000" /></bean><bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entrykey="cz.sweb.pichlik.springioc.propertyeditor.SpecialDateType"value="cz.sweb.pichlik.springioc.propertyeditor.SpecialDatePropertyEditor"/></map></property></bean>je definovanásespeciálnímtypemuvedeným jako Stringo jehož konverzi se stará PropertyEditorpatřičně zaregistrovanýTuesday 28 May 13
  • ValidateTuesday 28 May 13
  • • Řešeno přes Bean Validation• JSR 303• Možnost použití přes různé int.• org.springframework.validation• javax.validation.Validator• Integrace do Spring MVCTuesday 28 May 13
  • @Servicepublic class MyService {@Autowiredprivate Validator validator;public void doSomethingWithPerson(Person person){Set<ConstraintViolation<Person>> resultOfValidation = validator.validate(person);for (ConstraintViolation<Person> constraintViolation : resultOfValidation) {throw new IllegalArgumentException(constraintViolation.getMessage());}}}public class Person { @DecimalMax(value="110", message="Maximum age is 110") @DecimalMin(value="0", message="Minimum age is 0") private int age; @NotNull @Valid private Address address; public Person() { super(); } public Person(int age, Address address) { super(); this.age = age; this.address = address; }}<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />používávalidátorvalidujeJSR 303 validační anotaceTuesday 28 May 13
  • SPELTuesday 28 May 13
  • Spring EL• Expression Language• operátory, volání metod,proměnné a mnohem víc• přímé použití jako EL• definice beanTuesday 28 May 13
  • Použití• Jako EL ve vlastní aplikaci• V rámcí definice bean• Lze použít i v anotaci@ValueExpressionParser p = new SpelExpressionParser();Expression exp =p.parseExpression("Hello World.concat(!)");String message = (String) exp.getValue();<bean id="numberGuess" class="org.spring.samples.NumberGuess"><property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/></bean>Tuesday 28 May 13používání v definici bean vede k programování na úrovni XML => Ant syndrom
  • Vhodné použití• Enums, Constanty v XML<bean class="cz.sweb.pichlik.springioc.spel.ColorBean"><property name="color" value="#{ T(cz.sweb.pichlik.springioc.spel.Color).RED}" /></bean>Tuesday 28 May 13
  • IoC zbytekTuesday 28 May 13
  • DědičnostTuesday 28 May 13- sdileni definice vlastností mezi vice beanamy- nemá nic společného s objektovou hierarchií- společné property je možné přepsat v konkrétní beane
  • Integrace s existujícím kódemTuesday 28 May 13
  • Bean collecting• “Sběr” objektů určitého typu• Světlá strana autowiringuTuesday 28 May 13- umoznuje dosahovat dynamicke extensibility aplikace- podpora XML i anotaci
  • Anotace @Required• Hlídá nastavení závislostí• využití v kombinaci s XMLpublic class Bean { private String foo; @Required public void setFoo(String foo) { this.foo = foo; } }<bean class="Bean"><!--Missing declarationfoo property--></bean>Tuesday 28 May 13- predchazi NPE, kontainter selze pri bootu na chybejici zavislost
  • Nepřímé závislostiTuesday 28 May 13- 3rd party nebo legacy kod- pouzivat obezretne (v kodu neco smrdi)
  • Cyklické závislosti• Vyvarujte se jich• Špatný návrh API• IoC kontejner dokáže částečně řešitTuesday 28 May 13- fakci pouze pro setter injection
  • ProfilyTuesday 28 May 13
  • Spring Bean Definition profiles• Bean definition might be definedin a context activated on demand• Context may represent anenvironment or a strategy• Multiple profiles might beactivatedTuesday 28 May 13
  • Real/Mock example...<beans profile="real-backends"><mongo:mongo id="mongo" replica-set="${mongodb.replicaSet}"><mongo:optionsconnect-timeout="${mongodb.connectTimeout}"socket-timeout="${mongodb.socketTimeout}"write-timeout="${mongodb.writeTimeout}"write-number="${mongodb.writeNumber}"auto-connect-retry="true"socket-keep-alive="true"/></mongo:mongo></beans><beans profile="mocked-backends"><bean id="mongo" class="com.mongodb.Mongo" factory-bean="fongo" factory-method="getMongo"/><bean id="fongo" class="com.foursquare.fongo.Fongo"><constructor-arg value="gdc"></constructor-arg></bean></beans>Tuesday 28 May 13
  • Profile servlet aktivace<web-app version="2.4"xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">...<!--Activate profile with real-backends. This profile contains beans configuredagainst the real backend and not mocks. The profile might be changed duringintegration tests where mocked backends are used.--><context-param><param-name>spring.profiles.default</param-name><param-value>real-backends</param-value></context-param>...Tuesday 28 May 13
  • Profile aktivace v int. test/*** Common superclass for integration tests. This class turns on mocked backends.*/public abstract class AbstractWebappIntegrationTest extends AbstractIntegrationTest {...private static final String MOCKED_BACKENDS_PROFILE_NAME = "mocked-backends";/*** Activates profile with mocked*/@BeforeClasspublic static final void activateMockedBackends(){log.warn("Activating profile with mocked backends {}", MOCKED_BACKENDS_PROFILE_NAME);System.setProperty("spring.profiles.active", MOCKED_BACKENDS_PROFILE_NAME);}...}Tuesday 28 May 13
  • Aktivace profilu• Context ini param in web.xml• spring.profiles.default• spring.profiles.active• Programmatically• ConfigurableEnvironment.setActiveProfiles()• System property• spring.profiles.activeTuesday 28 May 13
  • Profile gotchas• Musí být definován na konci XMLsouboru• Beany nejsou ani parsovány pokudnení profil aktivní• Profil default může být použit jakovýchozí• Alternativa k spring.profiles.defaultTuesday 28 May 13Může vést k tomu, že pokud není profil zapnutý, nevíme jestli je vůbec daná část XML správně
  • Více o profilech• http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/• http://blog.springsource.org/2011/02/14/spring-3-1-m1-introducing-profile/Tuesday 28 May 13
  • Praktické cvičeníTuesday 28 May 13
  • 1.) Nadefinujte nekolik bean Book v XML2.) Upravte implementaci MemoryBookStoreDao, aby se automatickysebraly beany typu Book do Listu3.) Presunte konfiguraci cesty pro FileSystemBookStoreDao do Propertiessouboru4.) Overte testem, ze obe implementace MemoryBookStoreDao po tetozmene fungujiUkazka - autowiringu na objektech, ktere nejsou beanyTuesday 28 May 13
  • Čeho se vyvarovatTuesday 28 May 13
  • Programový bean lookup• Používat velice obezřetně!• Uvnitř bean speciálně• NPE• Nepřímé závislostiTuesday 28 May 13- pouze mimo IoC kontext- prakticke opodstatneni legacy kod a nebo problem singleton vs. prototyp
  • Statické holdery• Funguje jenom pro singleton beany• Znemožňuje reload instanceTuesday 28 May 13
  • Vykutálený pomocník• Musí být inicializován jako první• Obchází DI• WebApplicationContextUtilsTuesday 28 May 13
  • Závěrečná doporučeníTuesday 28 May 13
  • • Předejděte náhodnému mixování XML aanotací• Používejte @Qualifier pokud si nejste jistí• V případě XML použijte @Required• Nepoužívejte programový lookup bean pokudto neni nezbytně nutné• Pozor na mixování singleton a prototypescopeTuesday 28 May 13