You are on page 1of 94

Ni dung trnh by

2-1. Creating Beans by Invoking a Static Factory Method 2-2. Creating Beans by Invoking an Instance Factory Method 2-3. Declaring Beans from Static Fields 2-4. Declaring Beans from Object Properties 2-5. Using the Spring Expression Language 2-6. Setting Bean Scopes

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Ni dung trnh by
2-7. Customizing Destruction Bean Initialization and

2-8. Reducing XML Configuration with Java Config 2-9. Making Beans Aware of the Container 2-10. Loading External Resources 2-11. Creating Bean Post Processors 2-12. Externalizing Bean Configurations

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-1. CREATING BEANS BY INVOKING A STATIC FACTORY METHOD

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-1. Creating Beans by Invoking a Static Factory Method


Problem

You would like to create a bean in the Spring IoC container by invoking a static factory method, whose purpose is to encapsulate the object-creation process in a static method.
The client who requests an object can simply make a call to this method without knowing about the creation detail.

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-1. Creating Beans by Invoking a Static Factory Method Solution

Spring supports creating a bean by invoking a static factory method, which should be specified in the factory-method attribute.

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 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); } throw new IllegalArgumentException("Unknown product"); } }

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 <beans ...> <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> </beans>

1 2

Product aaa = ProductCreator.createProduct("aaa"); Product cdrw = ProductCreator.createProduct("cdrw");

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-2. CREATING BEANS BY INVOKING AN INSTANCE FACTORY METHOD

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-2. Creating Beans by Invoking an Instance Factory Method


Problem

You would like to create a bean in the Spring IoC container by invoking an instance factory method, whose purpose is to encapsulate the object-creation process in a method of another object instance.
The client who requests an object can simply make a call to this method without knowing about the creation detail.

10

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-2. Creating Beans by Invoking an Instance Factory Method Solution

Spring supports creating a bean invoking an instance factory method.

by

The bean instance should be specified in the factory-bean attribute, while the factory method should be specified in the factory method attribute.

11

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.apress.springrecipes.shop; 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"); } }

12

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
13

<beans ...> <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> </map> </property> </bean>
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 <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>

14

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 ProductCreator productCreator = new ProductCreator(); productCreator.setProducts(...); Product aaa = productCreator.createProduct("aaa"); Product cdrw = productCreator.createProduct("cdrw");

15

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-3. DECLARING BEANS FROM STATIC FIELDS

16

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-3. Declaring Beans from Static Fields


Problem

You would like to declare a bean in the Spring IoC container from a static field.
In Java, constant values declared as static fields. are often

17

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-3. Declaring Beans from Static Fields


Solution

To declare a bean from a static field, you can make use of either the built-in factory bean FieldRetrievingFactoryBean, or the <util:contant>tag in Spring 2.x.

18

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 package com.apress.springrecipes.shop; public abstract class Product { public static final Product AAA = new Battery("AAA", 2.5); public static final Product CDRW = new Disc("CD-RW", 1.5); ... }

19

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2
20

<beans ...> <bean id="aaa" class="org.springframework.beans.factory.config. FieldRetrievingFactoryBean"> <property name="staticField"> <value>com.apress.springrecipes.shop.Product.AAA</value> </property> </bean> <bean id="cdrw" class="org.springframework.beans.factory.config. FieldRetrievingFactoryBean"> <property name="staticField"> <value>com.apress.springrecipes.shop.Product.CDRW</value> </property> </bean> </beans> Product aaa = com.apress.springrecipes.shop.Product.AAA; Product cdrw = com.apress.springrecipes.shop.Product.CDRW;
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 <beans ...> <bean id="com.apress.springrecipes.shop.Product.AAA" class="org.springframework.beans.factory.config. FieldRetrievingFactoryBean" /> <bean id="com.apress.springrecipes.shop.Product.CDRW" class="org.springframework.beans.factory.config. FieldRetrievingFactoryBean" /> </beans>

21

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 <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"> <util:constant id="aaa" static-field="com.apress.springrecipes.shop.Product.AAA" /> <util:constant id="cdrw" static-field="com.apress.springrecipes.shop.Product.CDRW" /> </beans>

22

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-4. DECLARING BEANS FROM OBJECT PROPERTIES

23

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-4. Declaring Beans from Object Properties


Problem

You would like to declare a bean in the Spring IoC container from an object property or a nested property (i.e., a property path)

24

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-4. Declaring Beans from Object Properties


Solution

To declare a bean from an object property or a property path, you can make use of either the built-in factory bean PropertyPathFactoryBean or the <util:property-path> tag in Spring 2.x.

25

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.apress.springrecipes.shop; public class ProductRanking { private Product bestSeller; public Product getBestSeller() { return bestSeller; } public void setBestSeller(Product bestSeller) { this.bestSeller = bestSeller; } }

26

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <beans ...> <bean id="productRanking" class="com.apress.springrecipes.shop.ProductRanking"> <property name="bestSeller"> <bean class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> </bean> </property> </bean> <bean id="bestSeller" class="org.springframework.beans.factory.config. PropertyPathFactoryBean"> <property name="targetObject" ref="productRanking" /> <property name="propertyPath" value="bestSeller" /> </bean> </beans>

27

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 1 <bean id="productRanking.bestSeller" class="org.springframework.beans.factory.config. PropertyPathFactoryBean" /> Product bestSeller = productRanking.getBestSeller();

28

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 <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"> ... <util:property-path id="bestSeller" path="productRanking.bestSeller" /> </beans>

29

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 package com.apress.springrecipes.shop; public class Main { public static void main(String[] args) throws Exception { ... Product bestSeller = (Product) context.getBean("bestSeller"); System.out.println(bestSeller); } }

30

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-5. USING THE SPRING EXPRESSION LANGUAGE

31

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-5. Using the Spring Expression Language


Problem

You want to dynamically evaluate some condition or property and use it as the value configured in the IoC container.
Or perhaps you need to defer evaluation of something not at design time but at runtime, as might be the case in a custom scope. Or you just need a way to add a strong expression language to your own application.
32

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-5. Using the Spring Expression Language


Solution

Use Spring 3.0s Spring Expression Language (SpEL), which provides functionality similar to the Unified EL from JSF and JSP, or Object Graph Navigation Language (OGNL).
SpEL provides easy-to-use infrastructure that can be leveraged outside of the Spring container. Within the container, it can be used to make configuration much easier in a lot of cases.
33

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-6. SETTING BEAN SCOPES

34

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-6. Setting Bean Scopes


Problem

When you declare a bean in the configuration file, you are actually defining a template for bean creation, not an actual bean instance. When a bean is requested by the getBean() method or a reference from other beans.
Spring will decide which bean instance should be returned according to the bean scope. Sometimes, you have to set an appropriate scope for a bean other than the default scope.
35

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-6. Setting Bean Scopes


Solution

Singleton
Prototype Request

Session
GlobalSession

36

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 package com.apress.springrecipes.shop; public class ShoppingCart { private List<Product> items = new ArrayList<Product>(); public void addItem(Product item) { items.add(item); } public List<Product> getItems() { return items; } }

37

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <beans ...> <bean id="aaa" class="com.apress.springrecipes.shop.Battery"> <property name="name" value="AAA" /> <property name="price" value="2.5" /> </bean> <bean id="cdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="CD-RW" /> <property name="price" value="1.5" /> </bean> <bean id="dvdrw" class="com.apress.springrecipes.shop.Disc"> <property name="name" value="DVD-RW" /> <property name="price" value="3.0" /> </bean> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" /> </beans>

38

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("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());


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]

39

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 1 2 3 1 2 <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="singleton" /> <bean id="shoppingCart" class="com.apress.springrecipes.shop.ShoppingCart" scope="prototype" /> Shopping cart 1 contains [AAA 2.5, CD-RW 1.5] Shopping cart 2 contains [DVD-RW 3.0]

40

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-7. CUSTOMIZING BEAN INITIALIZATION AND DESTRUCTION

41

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-7. Customizing Bean Initialization and Destruction


Problem

Many real-world components have to perform certain types of initialization tasks before they are ready to be used. Such tasks include opening a file, opening a network/database connection, allocating memory, and so on.
They have to perform the corresponding destruction tasks at the end of their life cycle.

You have a need to customize bean initialization and destruction in the Spring IoC container.
42

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-7. Customizing Bean Initialization and Destruction Solution

The Spring IoC container is responsible for managing the life cycle of your beans, and it allows you to perform custom tasks at particular points of their life cycle. Your tasks should be encapsulated in callback methods for the Spring IoC container to call at a suitable time.

43

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-7. Customizing Bean Initialization and Destruction Solution

1. Create the bean instance either by a constructor or by a factory method.


2. Set the values and bean references to the bean properties.

3. Call methods.

the

initialization

callback

4. The bean is ready to be used.

5. When the container is shut down, call the destruction callback methods.
44

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
45

public class Cashier { private String name; private String path; private BufferedWriter writer; public void openFile() throws IOException { File logFile = new File(path, name + ".txt"); writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(logFile, true))); } public void checkout(ShoppingCart cart) throws IOException { double total = 0; for (Product product : cart.getItems()) { total += product.getPrice(); } writer.write(new Date() + "\t" + total + "\r\n"); writer.flush(); } public void closeFile() throws IOException { writer.close(); }
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 <beans ...> ... <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier"> <property name="name" value="cashier1" /> <property name="path" value="c:/cashier" /> </bean> </beans>

46

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 public class Main { public static void main(String[] args) throws Exception { ApplicationContext context = new FileSystemXmlApplicationContext("beans.xml"); Cashier cashier1 = (Cashier) context.getBean("cashier1"); cashier1.checkout(cart1); } }

47

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 package com.apress.springrecipes.shop; public class Cashier { ... public void openFile() throws IOException { File logFile = new File(path, name + ".txt"); writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(logFile, true))); } }

48

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

InitializingBean and DisposableBean


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.apress.springrecipes.shop; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class Cashier implements InitializingBean, DisposableBean { . . . public void afterPropertiesSet() throws Exception { openFile(); }

public void destroy() throws Exception { closeFile(); }


}

49

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

init-method and destroy-method Attributes


1 2 3 4 5 6 7 <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier" init-method="openFile" destroy-method="closeFile"> <property name="name" value="cashier1" /> <property name="path" value="c:/cashier" /> </bean>

50

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

@PostConstruct and @PreDestroy Annotations


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
51

package com.apress.springrecipes.shop; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class Cashier { . . . @PostConstruct public void openFile() throws IOException { File logFile = new File(path, name + ".txt"); writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(logFile, true))); } @PreDestroy public void closeFile() throws IOException { writer.close(); } }
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

@PostConstruct and @PreDestroy Annotations


1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10
52

<beans ...> <bean class="org.springframework.context.annotation. CommonAnnotationBeanPostProcessor" /> <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier"> <property name="name" value="cashier1" /> <property name="path" value="c:/cashier" /> </bean> </beans> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context3.0.xsd"> <context:annotation-config /> </beans>
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-8. REDUCING XML CONFIGURATION WITH JAVA CONFIG

53

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-8. Reducing XML Configuration with Java Config


Problem

You enjoy the power of the DI container but want to override some of the configuration, or you simply want to move more configuration out of the XML format and into Java where you can better benefit from refactoring and type safety.

54

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-8. Reducing XML Configuration with Java Config Solution

You can use Java Config, a project which has been in incubation since early 2005 long before Google Guice hit the sceneand has recently been folded into the core framework.

55

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("myApplicationContext.xml"); ... <context:annotation-config /> <context:component-scan base-package="com.my.base.package" /> ...

56

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 1 2 3 @Configuration public class PersonConfiguration { @Bean public Person josh() { Person josh = new Person(); josh.setName("Josh"); return josh; } } <bean id="josh" class="com.apress.springrecipes.spring3.javaconfig.Person" p:name="Josh" />

57

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 @Bean(name="theArtistFormerlyKnownAsJosh") public Person josh() { // }
ApplicationContext context = ; Person person = context.getBean("theArtistFormerlyKnownAsJosh", Person.class);

58

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6
1 2 3 4 5 6 7

@Bean( initMethod = "startLife", destroyMethod = "die") public Person companyLawyer() { Person companyLawyer = new Person(); companyLawyer.setName("Alan Crane"); return companyLawyer; }
@Bean public Person companyLawyer() { Person companyLawyer = new Person(); companyLawyer.startLife() ; companyLawyer.setName("Alan Crane"); return companyLawyer; }

59

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Configuration public class PetConfiguration { @Bean public Cat cat(){ return new Cat(); } @Bean public Person master(){ Person person = new Person() ; person.setPet( cat() ); return person; } // }

60

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Configuration @Import(AttorneyConfiguration.class) public class LawFirmConfiguration { @Value("#{denny}") private Attorney denny; @Value("#{alan}") private Attorney alan; @Value("#{shirley}") private Attorney shirley;
@Bean public LawFirm bostonLegal() { LawFirm lawFirm = new LawFirm(); lawFirm.setLawyers(Arrays.asList(denny, alan, shirley)); lawFirm.setLocation("Boston"); return lawFirm; } }

61

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-9. MAKING BEANS AWARE OF THE CONTAINER

62

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-9. Making Beans Aware of the Container


Problem

A well-designed component should not have direct dependencies on its container. However, sometimes its necessary for your beans to be aware of the containers resources.

63

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-9. Making Beans Aware of the Container Solution

Your beans can be aware of the Spring IoC containers resources by implementing certain aware interfaces, as shown in Table 2-3. Spring will inject the corresponding resources to your beans via the setter methods defined in these interfaces.

64

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-9. Making Beans Aware of the Container Solution

65

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-9. Making Beans Aware of the Container


Solution 1. Create the bean instance either constructor or by a factory method. by a

2. Set the values and bean references to the bean properties.

3. Call the setter methods defined in the aware interfaces.


4. 5. Call the initialization callback methods. The bean is ready to be used.

6. When the container is shut down, call the destruction callback methods.
66

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 1 2 3 4 package com.apress.springrecipes.shop;
import org.springframework.beans.factory.BeanNameAware; public class Cashier implements BeanNameAware { . . . public void setBeanName(String beanName) { this.name = beanName; } }

<bean id="cashier1" class="com.apress.springrecipes.shop.Cashier"> <property name="path" value="c:/cashier" /> </bean>

67

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-10. LOADING EXTERNAL RESOURCES

68

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-10. Loading External Resources


Problem

Sometimes, your application may need to read external resources (e.g., text files, XML files, properties file, or image files) from different locations (e.g., a file system, classpath, or URL).
Usually, you have to deal with different APIs for loading resources from different locations.

69

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-10. Loading External Resources


Solution

Springs resource loader provides a unified getResource() method for you to retrieve an external resource by a resource path. You can specify different prefixes for this path to load resources from different locations. To load a resource from a file system, you use the file prefix. To load a resource from the classpath, you use the classpath prefix. You may also specify a URL in this resource path.
70

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
71

public class BannerLoader implements ResourceLoaderAware { private ResourceLoader resourceLoader; public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public void showBanner() throws IOException { Resource banner = resourceLoader.getResource("file:banner.txt"); 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(); } }
Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 <bean id="bannerLoader" class="com.apress.springrecipes.shop.BannerLoader" init-method="showBanner" />

72

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Resource Prefixes
Relative path : file:banner.txt

Absolute path: file:c:/shop/banner.txt


Classpath classpath:banner.txt

classpath:com/apress/springrecipes/shop/ba nner.txt
URL http://springrecipes.apress.com/shop/banne r.txt
73

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Injecting Resources
1 2 3 4 5 6 7 8 9 10 11 public class BannerLoader { private Resource banner;
public void setBanner(Resource banner) { this.banner = banner; } public void showBanner() throws IOException { InputStream in = banner.getInputStream(); ... } }

74

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Injecting Resources
1 2 3 4 5 6 7 8 9 <bean id="bannerLoader" class="com.apress.springrecipes.shop.BannerLoader" init-method="showBanner"> <property name="banner"> <value> classpath:com/apress/springrecipes/shop/banner.txt </value> </property> </bean>

75

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-11. CREATING BEAN POST PROCESSORS

76

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-11. Creating Bean Post Processors


Problem

You would like to register your own plug-ins in the Spring IoC container to process the bean instances during construction.

77

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-11. Creating Bean Post Processors


Solution

A bean post processor allows additional bean processing before and after the initialization callback method. The main characteristic of a bean post processor is that it will process all the bean instances in the IoC container one by one, not just a single bean instance.
Typically, bean post processors are used for checking the validity of bean properties or altering bean properties according to particular criteria.
78

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-11. Creating Bean Post Processors


Solution

1. Create the bean instance either by a constructor or by a factory method.


2. Set the values and bean references to the bean properties. 3. Call the setter methods defined in the aware interfaces. 4. Pass the bean instance to the postProcessBeforeInitialization() method of each bean post processor.
79

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-11. Creating Bean Post Processors


Solution

5. Call methods

the

initialization

callback
the of

6. Pass the bean instance to postProcessAfterInitialization()method each bean post processor. 7. The bean is ready to be used.

8. When the container is shut down, call the destruction callback methods.

80

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
Suppose you would like to ensure that the logging path of Cashier exists before the logging file is open. This is to avoid FileNotFoundException. As this is a common requirement for all components that require storage in the file system, you had better implement it in a general and reusable manner. A bean post processor is an ideal choice to implement such a feature in Spring.

81

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5
1 2 3 4 5 6 7 8

package com.apress.springrecipes.shop;
public interface StorageConfig { public String getPath(); } package com.apress.springrecipes.shop; public class Cashier implements BeanNameAware, StorageConfig { public String getPath() { return path; } }

82

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class PathCheckingBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof StorageConfig) String path = ((StorageConfig) bean).getPath(); File file = new File(path); if (!file.exists()) { file.mkdirs(); } } return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }

83

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 <beans ...> ... <bean class="com.apress.springrecipes.shop.PathCheckingBeanPostProcessor" /> <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier" init-method="openFile" destroy-method="closeFile"> ... </bean> </beans>

84

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
If the cashier bean relies on the JSR-250 annotations @PostConstruct and @PreDestroy, and also a CommonAnnotationBeanPostProcessor instance to call the initialization method, your PathCheckingBeanPostProcessor will not work properly. Your bean post processor has a lower priority than CommonAnnotationBeanPostProcessor by default.

The initialization method before your path checking.


85

will

be

called

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 public class PathCheckingBeanPostProcessor implements BeanPostProcessor, PriorityOrdered { private int order;
public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } }

86

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 <beans ...> ... <bean class="org.springframework.context.annotation. CommonAnnotationBeanPostProcessor" /> <bean class="com.apress.springrecipes.shop. PathCheckingBeanPostProcessor"> <property name="order" value="0" /> </bean> <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier"> <property name="path" value="c:/cashier" /> </bean> </beans>

87

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-12. EXTERNALIZING BEAN CONFIGURATIONS

88

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-12. Externalizing Bean Configurations


Problem

When configuring beans in the configuration file, you must remember that its not a good practice to mix deployment details, such as the file path, server address, username, and password, with your bean configurations.
Usually, the bean configurations are written by application developers while the deployment details are matters for the deployers or system administrators.

89

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

2-12. Externalizing Bean Configurations


Solution

Spring comes with a bean factory post processor called PropertyPlaceholderConfigurer for you to externalize part of the bean configurations into a properties file. You can use variables of the form ${var} in your bean configuration file.
PropertyPlaceholderConfigurer will load the properties from a properties file and use them to replace the variables.
90

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

How It Works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
config.properties cashier.path=c:/cashier ----------------------------------------------<beans ...> ... <bean class="org.springframework.beans.factory.config. PropertyPlaceholderConfigurer"> <property name="location"> <value>config.properties</value> </property> </bean> <bean id="cashier1" class="com.apress.springrecipes.shop.Cashier"> <property name="path" value="${cashier.path}" /> </bean> </beans>

91

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Summary
Various ways of creating a bean, which include invoking a constructor, invoking a static/instance factory method, using a factory bean, and retrieving it from a static field/object property. Customize the initialization and destruction of your beans by specifying the corresponding callback methods. Certain advanced IoC container features, such as externalizing bean configuration into properties files
92

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

Ti liu tham kho


Slide bi ging ny c trch t sch:

Spring Recipes: A Problem-Solution Approach by Gary Mak, Daniel Rubio and Josh Long (Sep 1, 2010).

93

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

HI V P

94

Nguyn Hong Anh nhanh@fit.hcmus.edu.vn H KHTN - 2013

You might also like