1、Manage and Configure POJOs with the Spring IoC Container
创建POPJ Class
package com.apress.springrecipes.sequence; public class SequenceGenerator { private String prefix; private String suffix; private int initial; private int counter; public SequenceGenerator() {} public SequenceGenerator(String prefix, String suffix, int initial) { this.prefix = prefix; this.suffix = suffix; this.initial = initial; } public void setPrefix(String prefix) { this.prefix = prefix; } public void setSuffix(String suffix) { this.suffix = suffix; } public void setInitial(int initial) { this.initial = initial; } public synchronized String getSequence() { StringBuffer buffer = new StringBuffer(); buffer.append(prefix); buffer.append(initial + counter++); buffer.append(suffix); return buffer.toString(); } }
XML配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="prefix" value="30" /> <property name="suffix" value="A" /> <property name="initial" value="100000" /> </bean </beans>
实例化Spring IoC Container,并通过IoC Container创建POPJ
package com.apress.springrecipes.sequence; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); SequenceGenerator generator = (SequenceGenerator) context.getBean("sequenceGenerator"); System.out.println(generator.getSequence()); System.out.println(generator.getSequence()); } }
2、Create POJOs by Invoking a Constructor
Product.java
package com.apress.springrecipes.shop; public abstract class Product { private String name; private double price; public Product() {} public Product(String name, double price) { this.name = name; this.price = price; } // Getters and Setters public void setName(String name) { this.name = name; } public void setPrice(double price) { this.price = price; } public String getName() { return name; } public double getPrice() { return price; } public String toString() { return name + " " + price; } }
Dis.java
package com.apress.springrecipes.shop; public class Disc extends Product { private int capacity; public Disc() { super(); } public Disc(String name, double price) { super(name, price); } // Getters and Setters public void setCapacity(int capacity) { this.capacity = capacity; } public int getCapacity() { return capacity; } }
Battery.java
package com.apress.springrecipes.shop; public class Battery extends Product { private boolean rechargeable; public Battery() { super(); } public Battery(String name, double price) { super(name, price); } // Getters and Setters public void setRechargeable(boolean rechargeable) { this.rechargeable = rechargeable; } public boolean getRechargeable() { return rechargeable; } }
配置beans.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!-- 当没有constructor-arg时,调用默认构造器创建bean,否则寻找最合适的构造器; 然后再property的属性通过setter方法初始化 --> <!-- Product aaa = new Battery(); aaa.setName("AAA"); aaa.setPrice(2.5); aaa.setRechargeable(true); Product cdrw = new Disc(); cdrw.setName("CD-RW"); cdrw.setPrice(1.5); cdrw.setCapacity(700); --> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <!-- Product aaa = new Battery("AAA", 2.5); aaa.setRechargeable(true); Product cdrw = new Disc("CD-RW", 1.5); cdrw.setCapacity(700); --> <!-- constructor-arg标签可以通过添加type属性(int、java.lang.String等)、 name属性(形参名词)、index属性(参数顺序)等来进一步限定,进而找到最合适的构造器。 --> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <constructor-arg value="AAA" /> <constructor-arg value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <constructor-arg value="CD-RW" /> <constructor-arg value="1.5" /> <property name="capacity" value="700" /> </bean> </beans>
实例化
package com.apress.springrecipes.shop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) throws Exception { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); Product aaa = (Product) context.getBean("aaa"); Product cdrw = (Product) context.getBean("cdrw"); System.out.println(aaa); System.out.println(cdrw); } }
3、Use POJO References, Auto-Wiring, and Imports to Interact with Other POJOs
SequenceGenerator引用了一个PrefixGenerator
package com.apress.springrecipes.sequence; public interface PrefixGenerator { public String getPrefix(); }
package com.apress.springrecipes.sequence; import java.text.SimpleDateFormat; import java.text.DateFormat; import java.util.Date; public class DatePrefixGenerator implements PrefixGenerator { private DateFormat formatter; public void setPattern(String pattern) { this.formatter = new SimpleDateFormat(pattern); } public String getPrefix() { return formatter.format(new Date()); } }
package com.apress.springrecipes.sequence; public class SequenceGenerator { private PrefixGenerator prefixGenerator; private String suffix; private int initial; private int counter; public SequenceGenerator() {} public SequenceGenerator(PrefixGenerator prefixGenerator, String suffix, int initial) { this.prefixGenerator = prefixGenerator; this.suffix = suffix; this.initial = initial; } public void setPrefixGenerator(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; } public void setSuffix(String suffix) { this.suffix = suffix; } public void setInitial(int initial) { this.initial = initial; } public synchronized String getSequence() { StringBuffer buffer = new StringBuffer(); buffer.append(prefixGenerator.getPrefix()); buffer.append(initial + counter++); buffer.append(suffix); return buffer.toString(); } }
配置XML
<!-- 引用一个bean --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="datePrefixGenerator" class="com.apress.springrecipes.sequence.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator" ref="datePrefixGenerator" /> </bean> </beans> <!--constructor-arg 引用bean--> <!-- <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <constructor-arg ref="datePrefixGenerator" /> <property name="initial" value="100000" /> <property name="suffix" value="A" /> </bean> --> <!-- 用一个自定义的标签p声明 --> <!-- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="datePrefixGenerator" class="com.apress.springrecipes.sequence.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator" p:suffix="A" p:initial="1000000" p:prefixGenerator-ref="datePrefixGenerator" /> </beans> --> <!-- 引用内部bean--> <!-- <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="initial" value="100000" /> <property name="suffix" value="A" /> <property name="prefixGenerator"> <bean class="com.apress.springrecipes.sequence.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> </property> </bean> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <constructor-arg> <bean class="com.apress.springrecipes.sequence.DatePrefixGenerator"> <property name="pattern" value="yyyyMMdd" /> </bean> </constructor-arg> <property name="initial" value="100000" /> <property name="suffix" value="A" /> </bean> -->
使用bean
package com.apress.springrecipes.sequence; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); SequenceGenerator generator = (SequenceGenerator) context.getBean("sequenceGenerator"); System.out.println(generator.getSequence()); System.out.println(generator.getSequence()); } }
4、Configure POJOs with Java Collection Attributes
有集合属性的POPJ Class
package com.apress.springrecipes.sequence; import java.util.List; public class SequenceGenerator { private String prefix; private List<Object> suffixes; private int initial; private int counter; public SequenceGenerator() {} public SequenceGenerator(String prefix, List<Object> suffixes, int initial) { this.prefix = prefix; this.suffixes = suffixes; this.initial = initial; } public void setPrefix(String prefix) { this.prefix = prefix; } public void setSuffixes(List<Object> suffixes) { this.suffixes = suffixes; } public void setInitial(int initial) { this.initial = initial; } public synchronized String getSequence() { StringBuffer buffer = new StringBuffer(); buffer.append(prefix); buffer.append(initial + counter++); for (Object suffix : suffixes) { buffer.append("-"); buffer.append(suffix); } return buffer.toString(); } }
XML配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!-- List标签下的每一项可以是value(常量值)、ref(引用的bean)、 idref、<bean>(匿名内部bean)、<null/>(空值); Set与List的唯一区别是Set中的元素不会重复,也就意味着相同的值会被覆盖 --> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="prefix" value="30" /> <property name="initial" value="100000" /> <property name="suffixes"> <list> <value>A</value> <bean class="java.net.URL"> <constructor-arg value="http" /> <constructor-arg value="www.apress.com" /> <constructor-arg value="/" /> </bean> <null /> </list> </property> </bean> <!-- Map的定义方式为<key>和Value --> <!-- <bean id="sequenceGenerator"class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="prefix" value="30" /> <property name="initial" value="100000" /> <property name="suffixes"> <map> <entry> <key> <value>type</value> </key> <value>A</value> </entry> <entry key="type1" value="A" /> <entry> <key> <value>url</value> </key> <bean class="java.net.URL"> <constructor-arg value="http" /> <constructor-arg value="www.apress.com" /> <constructor-arg value="/" /> </bean> </entry> <entry key="url1"> <bean class="java.net.URL"> <constructor-arg value="http" /> <constructor-arg value="www.apress.com" /> <constructor-arg value="/" /> </bean> </entry> </map> </property> </bean> --> <!-- Properties与Map的区别为:Properties要求键值对均为String --> <!-- <bean id="sequenceGenerator"class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="prefix" value="30" /> <property name="initial" value="100000" /> <property name="suffixes"> <props> <prop key="type">A</prop> <prop key="url">http://www.apress.com/</prop> <prop key="null">null</prop> </props> </property> </bean> --> <!-- 指定集合元素类型type --> <!-- <property name="suffixes"> <list> <value type="int">5</value> <value type="int">10</value> <value type="int">20</value> </list> </property> --> <!-- 指定具体使用的集合对象,例如指定Set为TreeSet --> <!-- <property name="suffixes"> <bean class="org.springframework.beans.factory.config.SetFactoryBean"> <property name="targetSetClass"> <value>java.util.TreeSet</value> </property> <property name="sourceSet"> <set> <value>5</value> <value>10</value> <value>20</value> </set> </property> </bean> </property> --> <!-- 指定具体使用的集合对象,例如指定Set为TreeSet,使用util标签 --> <!-- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator"> <property name="prefix" value="30" /> <property name="initial" value="100000" /> <property name="suffixes"> <util:set set-class="java.util.TreeSet"> <value>5</value> <value>10</value> <value>20</value> </util:set> </property> </bean> </beans> --> </beans>
使用bean
package com.apress.springrecipes.sequence; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); SequenceGenerator generator = (SequenceGenerator) context.getBean("sequenceGenerator"); System.out.println(generator.getSequence()); System.out.println(generator.getSequence()); } }
5、Set a POJOs Scope
Spring中Scope分以下几种:
singleton -- Creates a single bean instance per Spring IoC container
prototype -- Creates a new bean instance each time when requested
request -- Creates a single bean instance per HTTP request; only valid in the context of a web application
session -- Creates a single bean instance per HTTP session; only valid in the context of a web application
globalSession -- Creates a single bean instance per global HTTP session; only valid in the context of a portalapplication
package com.apress.springrecipes.shop; public abstract class Product { private String name; private double price; public Product() {} public Product(String name, double price) { this.name = name; this.price = price; } // Getters and Setters public void setName(String name) { this.name = name; } public void setPrice(double price) { this.price = price; } public String getName() { return name; } public double getPrice() { return price; } public String toString() { return name + " " + price; } }
package com.apress.springrecipes.shop; public class Disc extends Product { private int capacity; public Disc() { super(); } public Disc(String name, double price) { super(name, price); } // Getters and Setters public void setCapacity(int capacity) { this.capacity = capacity; } public int getCapacity() { return capacity; } }
package com.apress.springrecipes.shop; public class Battery extends Product { private boolean rechargeable; public Battery() { super(); } public Battery(String name, double price) { super(name, price); } // Getters and Setters public void setRechargeable(boolean rechargeable) { this.rechargeable = rechargeable; } public boolean getRechargeable() { return rechargeable; } }
package com.apress.springrecipes.shop; import java.util.List; import java.util.ArrayList; public class ShoppingCart { private List<Product> items = new ArrayList<Product>(); public void addItem(Product item) { items.add(item); } public List<Product> getItems() { return items; } }
配置XML,默认scope为singleton
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="capacity" value="700" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" /> </beans>
main方法,执行结果为:
Shopping cart 1 contains [AAA 2.5, CD-RW 1.5]
Shopping cart 2 contains [AAA 2.5, CD-RW 1.5, DVD-RW 3.0]
package com.apress.springrecipes.shop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) throws Exception { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); Product aaa = (Product) context.getBean("aaa"); Product cdrw = (Product) context.getBean("cdrw"); Product dvdrw = (Product) context.getBean("dvdrw"); ShoppingCart cart1 = (ShoppingCart) context.getBean("shoppingCart"); cart1.addItem(aaa); cart1.addItem(cdrw); System.out.println("Shopping cart 1 contains " + cart1.getItems()); ShoppingCart cart2 = (ShoppingCart) context.getBean("shoppingCart"); cart2.addItem(dvdrw); System.out.println("Shopping cart 2 contains " + cart2.getItems()); } }
以上shoppingCart的配置相当于:
<bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="singleton" />
如果shoppingCart配置为:
<bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" />
main方法执行结果为:
Shopping cart 1 contains [AAA 2.5, CD-RW 1.5]
Shopping cart 2 contains [DVD-RW 3.0]
2.6 Use Data from External Resources
读取java classpath路径下的properties文件,文件内容:
specialcustomer.discount=0.1 summer.discount=0.15 endofyear.discount=0.2
在配置文件中读取properties的内容:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="discountPropertyConfigurer" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="location"> <value>classpath:discounts.properties</value> </property> <property name="ignoreResourceNotFound" value="true"/> <property name="ignoreUnresolvablePlaceholders" value="true"/> </bean> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="discount" value="${specialcustomer.discount:0}" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="discount" value="${summer.discount:0}" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="discount" value="${endofyear.discount:0}" /> <property name="capacity" value="700" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> </beans>
也可以在java代码中读取:
public class Main { public static void main(String[] args) throws Exception { Resource resource = new ClassPathResource("discounts.properties"); Properties props = PropertiesLoaderUtils.loadProperties(resource); System.out.println("And don't forget our discounts!"); System.out.println(props); } }
也可以直接加载某路径下的文件 或者 URL获取的文件:
Resource resource = new FileSystemResource("c:/shop/banner.txt") Resource resource = new UrlResource("http://www.apress.com/context/banner.txt")
读取classpath下的文件:
************************* * Welcome to My Shop! * *************************
设置一个POPJ类:
package com.apress.springrecipes.shop; import org.springframework.core.io.Resource; import java.io.IOException; import java.io.InputStream; import java.io.BufferedReader; import java.io.InputStreamReader; public class BannerLoader { private Resource banner; public void setBanner(Resource banner) { this.banner = banner; } public void showBanner() throws IOException { InputStream in = banner.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); while (true) { String line = reader.readLine(); if (line == null) break; System.out.println(line); } reader.close(); } }
初始化bean时,读取数据:
<bean id="bannerLoader" class="com.apress.springrecipes.shop.BannerLoader" init-method="showBanner"> <property name="banner"> <value>classpath:banner.txt</value> </property> </bean>
设置路径时候,还可以是:
file:c:/shop/banner.txt
classpath:banner.txt
http://springrecipes.apress.com/shop/banner.txt
2.7 Resolve I18N Text Messages for Different Locales in Properties Files
国际化文件:
配置国际化文件对应的bean
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:messages</value> </list> </property> <property name="cacheSeconds" value="1"/> </bean> </beans>
使用国际化:
package com.apress.springrecipes.shop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import java.util.Locale; import java.util.Date; public class Main { public static void main(String[] args) throws Exception { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); String alert = context.getMessage("alert.checkout", null, Locale.US); String alert_inventory = context.getMessage("alert.inventory.checkout", new Object[] { "[DVD-RW 3.0]", new Date() }, Locale.US); System.out.println("The I18N message for alert.checkout is: " + alert); System.out.println("The I18N message for alert.inventory.checkout is: " + alert_inventory); } }
2-8. Customize POJO Initialization and Destruction
初始化bean时的方法init-method和销毁bean时的方法destroy-method
Product.java、Battery.java、Disc.java同上
package com.apress.springrecipes.shop; import java.util.List; import java.util.ArrayList; public class ShoppingCart { private List<Product> items = new ArrayList<Product>(); public void addItem(Product item) { items.add(item); } public List<Product> getItems() { return items; } }
package com.apress.springrecipes.shop; import java.io.IOException; import java.io.File; import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.FileOutputStream; import java.util.Date; public class Cashier { private String fileName; private String path; private BufferedWriter writer; public void setFileName(String fileName) { this.fileName = fileName; } public void setPath(String path) { this.path = path; } public void openFile() throws IOException { File targetDir = new File(path); if (!targetDir.exists()) { targetDir.mkdir(); } File checkoutFile = new File(path, fileName + ".txt"); if(!checkoutFile.exists()) { checkoutFile.createNewFile(); } writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(checkoutFile, true))); } public void checkout(ShoppingCart cart) throws IOException { writer.write(new Date() + "\t" +cart.getItems() + "\r\n"); writer.flush(); } public void closeFile() throws IOException { writer.close(); } }配置XML
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="capacity" value="700" /> </bean> <bean id="shoppingCart" lazy-init="true" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> <bean id="cashier" class="com.apress.springrecipes.shop.Cashier" init-method="openFile" destroy-method="closeFile"> <property name="fileName" value="checkout" /> <property name="path" value="c:/Windows/Temp/cashier" /> </bean> </beans>lazy-init默认为false,如果为true,意味着,如果bean一直没有被应用初始化,那么,bean不会被初始化。
初始化bean时候会执行init-method,在bean最后销毁时会执行destroy-method。
package com.apress.springrecipes.shop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) throws Exception { ApplicationContext context = new GenericXmlApplicationContext("beans.xml"); Product aaa = (Product) context.getBean("aaa"); Product cdrw = (Product) context.getBean("cdrw"); Product dvdrw = (Product) context.getBean("dvdrw"); ShoppingCart cart1 = (ShoppingCart) context.getBean("shoppingCart"); cart1.addItem(aaa); cart1.addItem(cdrw); System.out.println("Shopping cart 1 contains " + cart1.getItems()); ShoppingCart cart2 = (ShoppingCart) context.getBean("shoppingCart"); cart2.addItem(dvdrw); System.out.println("Shopping cart 2 contains " + cart2.getItems()); Cashier cashier = (Cashier) context.getBean("cashier"); cashier.checkout(cart1); cashier.checkout(cart2); } }
如果希望一个bean初始化时比另外一个先,可以:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="sequenceGenerator" class="com.apress.springrecipes.sequence.SequenceGenerator" autowire="byType" depends-on="datePrefixGenerator"> <property name="initial" value="100000" /> <property name="suffix" value="A" /> </bean> <bean id="datePrefixGenerator" primary="true" class="com.apress.springrecipes.sequence.DatePrefixGenerator"> </bean> <bean id="numberprefixGenerator" class="com.apress.springrecipes.sequence.NumberPrefixGenerator"> </bean> </beans>示例中datePrefixGenerator会比sequenceGenerator先创建。
2.9 Create Post Processors to Validate and Modify POJOs
处理每个bean,可以继承BeanPostProcessor
Product.java、Battery.java、Disc.java、Cashier.java 、ShoppingCart.java 、Main.java均同2.8例,添加如下两个类,这两个类均继承BeanPostProcessor,这意味着每个bean都会被这两个类处理,该类有两方法,一个是初始化之前处理,一个是之后。
package com.apress.springrecipes.shop; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class AuditCheckBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("In AuditCheckBeanPostProcessor.postProcessBeforeInitialization, processing bean type: " + bean.getClass()); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
package com.apress.springrecipes.shop; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class ProductCheckBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Product) { String productName = ((Product) bean).getName(); System.out.println("In ProductCheckBeanPostProcessor.postProcessBeforeInitialization, processing Product: " + productName); } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Product) { String productName = ((Product) bean).getName(); System.out.println("In ProductCheckBeanPostProcessor.postProcessAfterInitialization, processing Product: " + productName); } return bean; } }在配置文件中需要配置相应的bean
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean class="com.apress.springrecipes.shop.ProductCheckBeanPostProcessor"/> <bean class="com.apress.springrecipes.shop.AuditCheckBeanPostProcessor"/> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="capacity" value="700" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> <bean id="cashier" class="com.apress.springrecipes.shop.Cashier" init-method="openFile" destroy-method="closeFile"> <property name="fileName" value="checkout" /> <property name="path" value="c:/Windows/Temp/cashier" /> </bean> </beans>
2-9. Create Post Processors to Validate and Modify POJOs
使用静态工厂方法初始化bean
package com.apress.springrecipes.shop; public class ProductCreator { public static Product createProduct(String productId) { if ("aaa".equals(productId)) { return new Battery("AAA", 2.5); } else if ("cdrw".equals(productId)) { return new Disc("CD-RW", 1.5); } else if ("dvdrw".equals(productId)) { return new Disc("DVD-RW", 3.0); } throw new IllegalArgumentException("Unknown product"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="aaa" class="com.apress.springrecipes.shop.ProductCreator" factory-method="createProduct"> <constructor-arg value="aaa" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.ProductCreator" factory-method="createProduct"> <constructor-arg value="cdrw" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.ProductCreator" factory-method="createProduct"> <constructor-arg value="dvdrw" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> </beans>通过某个bean的方法创建新的bean,例如
package com.apress.springrecipes.shop; import java.util.Map; public class ProductCreator { private Map<String, Product> products; public void setProducts(Map<String, Product> products) { this.products = products; } public Product createProduct(String productId) { Product product = products.get(productId); if (product != null) { return product; } throw new IllegalArgumentException("Unknown product"); } }
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="productCreator" class="com.apress.springrecipes.shop.ProductCreator"> <property name="products"> <map> <entry key="aaa"> <bean class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> </bean> </entry> <entry key="cdrw"> <bean class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> </bean> </entry> <entry key="dvdrw"> <bean class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> </bean> </entry> </map> </property> </bean> <bean id="aaa" factory-bean="productCreator" factory-method="createProduct"> <constructor-arg value="aaa" /> </bean> <bean id="cdrw" factory-bean="productCreator" factory-method="createProduct"> <constructor-arg value="cdrw" /> </bean> <bean id="dvdrw" factory-bean="productCreator" factory-method="createProduct"> <constructor-arg value="dvdrw" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> </beans>配置中,'aaa','cdrw','dvdrw'是通过id为productCreator的bean 的createProduct方法创建的。
2-11. Use Spring Environments and Profiles to Load Different Sets of POJOs
可以通过profile的给不同的配置加标签,然后根据实际情况激活。示例中profile分为五中:spring、summer、autumn、winter以及global,
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <beans profile="spring"> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="capacity" value="700" /> </bean> </beans> <beans profile="summer,winter"> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.0" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.0" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="2.5" /> <property name="capacity" value="700" /> </bean> </beans> <beans profile="autumn"> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> <property name="rechargeable" value="true" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> <property name="capacity" value="700" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> <property name="capacity" value="700" /> </bean> </beans> <beans profile="global"> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> <bean id="cashier" class="com.apress.springrecipes.shop.Cashier" init-method="openFile" destroy-method="closeFile"> <property name="fileName" value="checkout" /> <property name="path" value="c:/Windows/Temp/cashier" /> </bean> </beans> </beans>激活global和winter
package com.apress.springrecipes.shop; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { public static void main(String[] args) throws Exception { GenericXmlApplicationContext context = new GenericXmlApplicationContext(); context.getEnvironment().setActiveProfiles("global","winter"); context.load("beans.xml"); context.refresh(); Product aaa = (Product) context.getBean("aaa"); Product cdrw = (Product) context.getBean("cdrw"); Product dvdrw = (Product) context.getBean("dvdrw"); ShoppingCart cart1 = (ShoppingCart) context.getBean("shoppingCart"); cart1.addItem(aaa); cart1.addItem(cdrw); System.out.println("Shopping cart 1 contains " + cart1.getItems()); ShoppingCart cart2 = (ShoppingCart) context.getBean("shoppingCart"); cart2.addItem(dvdrw); System.out.println("Shopping cart 2 contains " + cart2.getItems()); Cashier cashier = (Cashier) context.getBean("cashier"); cashier.checkout(cart1); cashier.checkout(cart2); } }也可以用java命令的参数:-Dspring.profiles.active="global,winter"来执行。也可以在Spring的Servlet的 web.xml的配置来激活:
相关推荐
3. Spring Annotation Driven Core Tasks 4. Spring @MVC 5. Spring REST 6. Spring Deployment to the Cloud 7. Spring Social 8. Spring Security 9. Spring Mobile 10. Spring with other Web Frameworks 11. ...
Spring Core Tasks 这部分内容覆盖了 Spring 框架的核心功能,如依赖注入、面向切面编程等,这些都是 Spring 最基础也是最强大的特性之一。 #### 3. Spring Annotation-Driven Core Tasks 随着 Spring 的发展,...
Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP. Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient. ...
<bean id="lotteryNewsStatistic" class="com.aochuang.lotterynews.tasks.LotteryNewsStatistic" scope="singleton"> ``` ### 定时任务的实现 在Spring环境中实现定时任务主要依靠`@Scheduled`注解。下面...
- **加载Hadoop配置**:通过Spring配置文件中的`<hadoop:config>`元素加载Hadoop的配置文件,例如`core-site.xml`和`hdfs-site.xml`。 - **自定义配置属性**:可以在Spring配置文件中通过`<hadoop:property>`元素...
在不使用Maven的情况下,开发者需要手动下载并添加所有必要的依赖库,如Spring Boot Starter、Spring Core、Spring Web等。这些依赖通常会以jar文件的形式存储在一个特定的lib目录下,然后在运行时被加载。这需要对...
spring-core-5.0.6.RELEASE-sources.jar spring-core-5.0.6.RELEASE.jar spring-expression-5.0.6.RELEASE-javadoc.jar spring-expression-5.0.6.RELEASE-sources.jar spring-expression-5.0.6.RELEASE.jar ...
Spring provides the core container for managing beans and dependencies, Spring MVC handles the Model-View-Controller architecture, and MyBatis simplifies database interactions. The design of the ...
2. **Spring Framework (SSM)**: Spring forms the core of the 'S' in SSM, which stands for Spring, Servlets, and MyBatis. Spring is a comprehensive framework for building enterprise-level applications, ...
It also promotes modularity and dependency injection, allowing developers to focus on the core functionality of the application rather than getting bogged down in infrastructure details. This ...
A detailed design of the system's performance section is the core of the entire system design. The system will be practically implemented and monitored, with a conclusion summarizing the thesis. ...
Spring Boot, as a core technology in this system, offers a robust foundation for building scalable applications with minimal configuration. It simplifies the development process, allowing for faster ...
The core functionalities of the system may include: 1. **Product Management**: This module deals with adding, updating, and deleting product information, including details like product name, category...
The mini-program's core features include user and merchant registration and login, enabling both parties to access their respective dashboards. Merchants can upload and manage their product listings, ...
Spring provides the core container for managing components, SpringMVC handles the presentation layer, while MyBatis simplifies database operations. The system would consist of several key modules, ...
Spring, a core component of the SSM stack, provides dependency injection and manages the lifecycle of objects, promoting modularity and loose coupling. SpringMVC, another part of SSM, handles the ...
Spring provides core dependency injection and manages the application's lifecycle, SpringMVC handles web request handling and presentation layer tasks, while MyBatis simplifies database access by ...
This project, "基于JavaWeb的酒店管理信息系统的设计与实现", utilizes the popular SSH (Struts+Spring+Hibernate) framework for building a hotel management system. Developed with tools like MyEclipse, ...
The core functionalities of the vehicle management system include: 1. **基本信息管理**: This involves managing details such as vehicle information (make, model, registration number, maintenance ...