Spring框架基礎
1 什么是Spring框架泡挺?
Spring框架是框架的框架挺举,因為其提供了對如Structs妄痪,Hibernate,等框架的支持外冀,應用Spring框架可以解決不同的技術上的問題(開發(fā)網頁應用生闲?)媳溺。
Spring框架的優(yōu)勢:
- 預定義了許多模板。
封裝了JDBC碍讯,Hibernate悬蔽,JPA等許多模板。讓我們無需了解其具體技術細節(jié)就可以很輕松的使用它們捉兴。 - 代碼松耦合蝎困。
由依賴注入提供。 - 易于測試
也是因為依賴注入的特性 - 輕量級
由于POJO的存在轴术,Spring框架不需要程序員繼承任何類或者接口难衰。 - 快速部署
因為Spring框架支持不同的框架钦无,這使得它很容易開發(fā)JavaEE應用 - 強大的抽象
對JavaEE的抽象 - 提供聲明式支持
提供對緩存逗栽,驗證,事務和格式的聲明式支持失暂。
2 Spring模塊
- Test模塊
提供:使用JUnit和TestNG進行測試 - Core Container
- Core & Beans
提供IOC和依賴注入特性- Context
提供標準國際化彼宠,EJB,JMS弟塞,基礎遠程 - Expression Language
EL和JSP的擴展凭峡,提供支持:設置和獲取屬性值、方法調用决记、訪問集合摧冀、索引器、訪問變量系宫、邏輯和數學操作索昂,通過對象名檢索對象等
- Context
- AOP & Aspects & Instrumentation(檢測)
面向切面編程- Aspects
提供:與AspectJ集成 - Instrumentation
提供:類檢測、實現(xiàn)類加載器
- Aspects
- Data Access / Integration(數據訪問與集成)
與數據庫交互- JDBC
- ORM
- OXM
- JMS
- Transaction
- Web (MVC / Remoting)
創(chuàng)建Web應用- Web
- Web-Servlet
- Web-Struts
- Web-Portlet
- Core & Beans
3 Spring控制反轉和依賴注入的一個小例子
控制反轉和依賴注入:消除代碼中的依賴關系扩借。
Spring使用控制反轉和依賴注入來使程序達到松耦合的目的椒惨。
看一個小例子:
class Employee{
Address address;
Employee(){
address=new Address();
}
}
這個例子中,職員類依賴了地址類潮罪。創(chuàng)建職員類時康谆,先要創(chuàng)建地址類领斥。
class Employee{
Address address;
Employee(Address address){
this.address=address;
}
}
這個例子中,創(chuàng)建職員類時沃暗,由外部傳入地址類月洛,不用再在職員類中創(chuàng)建,實現(xiàn)了代碼的松耦合描睦。
4 Spring應用的一個小例子
用你喜歡的ide(或者不用ide)創(chuàng)建Java類Student.java:
package com.javatpoint;
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void displayInfo(){
System.out.println("Hello: "+name);
}
}
創(chuàng)建applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="studentbean" class="com.javatpoint.Student">
<property name="name" value="Vimal Jaiswal"></property>
</bean>
</beans>
創(chuàng)建測試類Test.java
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource resource=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(resource);
Student student=(Student)factory.getBean("studentbean");
student.displayInfo();
}
}
導入jar包膊存,jar包下載地址:jar包地址
運行Test.java:
- 讀取xml配置文件,存為resource
- 以resource創(chuàng)建一個beanFactory
- 從beanFactory中獲取在xml中定義好的bean "studentbean"
5 Spring IoC容器
IoC容器的功能:
- 實例化類
- 配置對象
- 組裝對象間的依賴
IoC容器從XML文件獲取信息并根據信息進行工作忱叭。
IoC容器類型有兩種:
- BeanFactory
- ApplicationContext
兩種IoC容器的區(qū)別:
ApplicationContext除了具有所有BeanFactory的功能之外隔崎,還提供了額外的功能:
- 集成Spring AOP
- 信息來源定位
- 事件傳播
- 提供web應用的應用層具體上下文
5.1 使用IoC容器
使用BeanFactory:
Resource resource =
new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
使用ApplicationContext:
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
6 依賴注入
依賴注入用以移除代碼之間的依賴關系,降低代碼間的耦合度韵丑。
依賴注入的方式有兩種:
- 構造器注入
- Setter注入
兩種注入方式的區(qū)別:
- 部分依賴注入只能通過Setter注入
- Setter注入會覆蓋構造器注入
- Setter注入可以輕松修改bean的值爵卒,更靈活
6.1 依賴查找(Dependency Lookup)
依賴查找是,當有一個依賴的需求時撵彻,獲取該依賴(資源钓株、對象)的方式
在不使用依賴注入時,依賴查找的方式(或者說new對象的方式陌僵,但后者范圍較小)有:
- new
A obj = new AImpl();
- 工廠方法模式
A obj = A.getA();
- JNDI(Java Naming Directory Interface)
Context ctx = new InitialContext();
Context environmentCtx = (Context) ctx.lookup("java:comp/env");
A obj = (A)environmentCtx.lookup("A");
以上依賴查找的方法的問題是:
- 緊耦合
- 不易測試
使用依賴注入的方式:
class Employee{
Address address;
Employee(Address address){
this.address=address;
}
public void setAddress(Address address){
this.address=address;
}
}
這樣的情況下轴合,地址類的實例由構造方法或Setter從外部源如XML文件獲得。
6.1 通過構造器注入基礎類型
Employee.java:
package com.javatpoint;
public class Employee {
private int id;
private String name;
public Employee() {System.out.println("def cons");}
public Employee(int id) {this.id = id;}
public Employee(String name) { this.name = name;}
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
void show(){
System.out.println(id+" "+name);
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="e" class="com.javatpoint.Employee">
<constructor-arg value="10" type="int"></constructor-arg>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.*;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Employee s=(Employee)factory.getBean("e");
s.show();
}
}
6.2 通過構造器注入字符串類型
將applicationContext.xml文件主內容修改如下:
<bean id="e" class="com.javatpoint.Employee">
<constructor-arg value="10" type="int" ></constructor-arg>
<constructor-arg value="Sonoo"></constructor-arg>
</bean>
6.3 通過構造器注入獨立對象
Address.java:
package com.javatpoint;
public class Address {
private String city;
private String state;
private String country;
public Address(String city, String state, String country) {
super();
this.city = city;
this.state = state;
this.country = country;
}
public String toString(){
return city+" "+state+" "+country;
}
}
Address包含三個屬性碗短,一個構造器和一個toString方法
Employee.java:
package com.javatpoint;
public class Employee {
private int id;
private String name;
private Address address;//Aggregation
public Employee() {System.out.println("def cons");}
public Employee(int id, String name, Address address) {
super();
this.id = id;
this.name = name;
this.address = address;
}
void show(){
System.out.println(id+" "+name);
System.out.println(address.toString());
}
}
Employee包含三個屬性id受葛,name,address(獨立對象)偎谁,兩個構造器和一個show方法
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="a1" class="com.javatpoint.Address">
<constructor-arg value="ghaziabad"></constructor-arg>
<constructor-arg value="UP"></constructor-arg>
<constructor-arg value="India"></constructor-arg>
</bean>
<bean id="e" class="com.javatpoint.Employee">
<constructor-arg value="12" type="int"></constructor-arg>
<constructor-arg value="Sonoo"></constructor-arg>
<constructor-arg>
<ref bean="a1"/>
</constructor-arg>
</bean>
</beans>
applicationContext.xml配置了兩個bean:
- Address
通過Address的構造器注入Address的三個屬性 - Employee
通過Employee的構造器注入Employee的兩個基礎類型总滩、字符串類型屬性,以及一個獨立對象類型
Test.java
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.*;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Employee s=(Employee)factory.getBean("e");
s.show();
}
}
6.4 通過構造器注入字符串集合
可以注入三種集合類型:
- List
- Set
- Map
Question.java
package com.javatpoint;
import java.util.Iterator;
import java.util.List;
public class Question {
private int id;
private String name;
private List<String> answers;
public Question() {}
public Question(int id, String name, List<String> answers) {
super();
this.id = id;
this.name = name;
this.answers = answers;
}
public void displayInfo(){
System.out.println(id+" "+name);
System.out.println("answers are:");
Iterator<String> itr=answers.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Question具有三個屬性巡雨,基礎類型id闰渔,字符串name,以及List集合answers
applicatoinContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="q" class="com.javatpoint.Question">
<constructor-arg value="111"></constructor-arg>
<constructor-arg value="What is java?"></constructor-arg>
<constructor-arg>
<list>
<value>Java is a programming language</value>
<value>Java is a Platform</value>
<value>Java is an Island of Indonasia</value>
</list>
</constructor-arg>
</bean>
</beans>
applicationContext配置了一個Question的bean:q铐望,通過構造器注入三個屬性
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.5 通過構造器注入對象類型集合
Question.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.List;
public class Question {
private int id;
private String name;
private List<Answer> answers;
public Question() {}
public Question(int id, String name, List<Answer> answers) {
super();
this.id = id;
this.name = name;
this.answers = answers;
}
public void displayInfo(){
System.out.println(id+" "+name);
System.out.println("answers are:");
Iterator<Answer> itr=answers.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Question包含三個屬性冈涧,基礎類型id,字符串name正蛙,內容為Answer對象的集合
Answer.java:
package com.javatpoint;
public class Answer {
private int id;
private String name;
private String by;
public Answer() {}
public Answer(int id, String name, String by) {
super();
this.id = id;
this.name = name;
this.by = by;
}
public String toString(){
return id+" "+name+" "+by;
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="ans1" class="com.javatpoint.Answer">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="Java is a programming language"></constructor-arg>
<constructor-arg value="John"></constructor-arg>
</bean>
<bean id="ans2" class="com.javatpoint.Answer">
<constructor-arg value="2"></constructor-arg>
<constructor-arg value="Java is a Platform"></constructor-arg>
<constructor-arg value="Ravi"></constructor-arg>
</bean>
<bean id="q" class="com.javatpoint.Question">
<constructor-arg value="111"></constructor-arg>
<constructor-arg value="What is java?"></constructor-arg>
<constructor-arg>
<list>
<ref bean="ans1"/>
<ref bean="ans2"/>
</list>
</constructor-arg>
</bean>
</beans>
applicationContext定義了兩個Answer的bean: ans1, ans2, 以及一個Question的bean:q(利用兩個ans構造)
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.6 通過構造器注入字符串類型映射集合
Question.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class Question {
private int id;
private String name;
private Map<String,String> answers;
public Question() {}
public Question(int id, String name, Map<String, String> answers) {
super();
this.id = id;
this.name = name;
this.answers = answers;
}
public void displayInfo(){
System.out.println("question id:"+id);
System.out.println("question name:"+name);
System.out.println("Answers....");
Set<Entry<String, String>> set=answers.entrySet();
Iterator<Entry<String, String>> itr=set.iterator();
while(itr.hasNext()){
Entry<String,String> entry=itr.next();
System.out.println("Answer:"+entry.getKey()+" Posted By:"+entry.getValue());
}
}
}
Question包含三個屬性督弓,id,name跟畅,字符串->字符串映射集合answers
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="q" class="com.javatpoint.Question">
<constructor-arg value="11"></constructor-arg>
<constructor-arg value="What is Java?"></constructor-arg>
<constructor-arg>
<map>
<entry key="Java is a Programming Language" value="Ajay Kumar"></entry>
<entry key="Java is a Platform" value="John Smith"></entry>
<entry key="Java is an Island" value="Raj Kumar"></entry>
</map>
</constructor-arg>
</bean>
</beans>
applicationContext配置了一個Question的bean:q
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.7 通過構造器注入對象類型映射集合
Question.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class Question {
private int id;
private String name;
private Map<Answer,User> answers;
public Question() {}
public Question(int id, String name, Map<Answer, User> answers) {
super();
this.id = id;
this.name = name;
this.answers = answers;
}
public void displayInfo(){
System.out.println("question id:"+id);
System.out.println("question name:"+name);
System.out.println("Answers....");
Set<Entry<Answer, User>> set=answers.entrySet();
Iterator<Entry<Answer, User>> itr=set.iterator();
while(itr.hasNext()){
Entry<Answer, User> entry=itr.next();
Answer ans=entry.getKey();
User user=entry.getValue();
System.out.println("Answer Information:");
System.out.println(ans);
System.out.println("Posted By:");
System.out.println(user);
}
}
}
Question包含三個屬性咽筋,其中一個屬性為Answer->User映射類型集合
Answer.java:
package com.javatpoint;
import java.util.Date;
public class Answer {
private int id;
private String answer;
private Date postedDate;
public Answer() {}
public Answer(int id, String answer, Date postedDate) {
super();
this.id = id;
this.answer = answer;
this.postedDate = postedDate;
}
public String toString(){
return "Id:"+id+" Answer:"+answer+" Posted Date:"+postedDate;
}
}
User.java:
package com.javatpoint;
public class User {
private int id;
private String name,email;
public User() {}
public User(int id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
public String toString(){
return "Id:"+id+" Name:"+name+" Email Id:"+email;
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="answer1" class="com.javatpoint.Answer">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="Java is a Programming Language"></constructor-arg>
<constructor-arg value="12/12/2001"></constructor-arg>
</bean>
<bean id="answer2" class="com.javatpoint.Answer">
<constructor-arg value="2"></constructor-arg>
<constructor-arg value="Java is a Platform"></constructor-arg>
<constructor-arg value="12/12/2003"></constructor-arg>
</bean>
<bean id="user1" class="com.javatpoint.User">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="Arun Kumar"></constructor-arg>
<constructor-arg value="arun@gmail.com"></constructor-arg>
</bean>
<bean id="user2" class="com.javatpoint.User">
<constructor-arg value="2"></constructor-arg>
<constructor-arg value="Varun Kumar"></constructor-arg>
<constructor-arg value="Varun@gmail.com"></constructor-arg>
</bean>
<bean id="q" class="com.javatpoint.Question">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="What is Java?"></constructor-arg>
<constructor-arg>
<map>
<entry key-ref="answer1" value-ref="user1"></entry>
<entry key-ref="answer2" value-ref="user2"></entry>
</map>
</constructor-arg>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.8 通過構造器注入繼承bean
Employee.java:
package com.javatpoint;
public class Employee {
private int id;
private String name;
private Address address;
public Employee() {}
public Employee(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Employee(int id, String name, Address address) {
super();
this.id = id;
this.name = name;
this.address = address;
}
void show(){
System.out.println(id+" "+name);
System.out.println(address);
}
}
Address.java:
package com.javatpoint;
public class Address {
private String addressLine1,city,state,country;
public Address(String addressLine1, String city, String state, String country) {
super();
this.addressLine1 = addressLine1;
this.city = city;
this.state = state;
this.country = country;
}
public String toString(){
return addressLine1+" "+city+" "+state+" "+country;
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="e1" class="com.javatpoint.Employee">
<constructor-arg value="101"></constructor-arg>
<constructor-arg value="Sachin"></constructor-arg>
</bean>
<bean id="address1" class="com.javatpoint.Address">
<constructor-arg value="21,Lohianagar"></constructor-arg>
<constructor-arg value="Ghaziabad"></constructor-arg>
<constructor-arg value="UP"></constructor-arg>
<constructor-arg value="USA"></constructor-arg>
</bean>
<bean id="e2" class="com.javatpoint.Employee" parent="e1">
<constructor-arg ref="address1"></constructor-arg>
</bean>
</beans>
employee1使用傳統(tǒng)方式構造bean,employee2使用bean繼承方式構造bean
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Employee e1=(Employee)factory.getBean("e2");
e1.show();
}
}
6.9 通過Setter注入基礎類型徊件、String類型
Employee.java:
package com.javatpoint;
public class Employee {
private int id;
private String name;
private String city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
void display(){
System.out.println(id+" "+name+" "+city);
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="obj" class="com.javatpoint.Employee">
<property name="id">
<value>20</value>
</property>
<property name="name">
<value>Arun</value>
</property>
<property name="city">
<value>ghaziabad</value>
</property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.*;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Employee e=(Employee)factory.getBean("obj");
e.display();
}
}
6.10 通過Setter注入對象類型
Address.java:
package com.javatpoint;
public class Address {
private String addressLine1, city, state, country;
//getters and setters
public String toString() {
return addressLine1 + " " + city + " " + state + " " + country;
}
}
Employee.java:
package com.javatpoint;
public class Employee {
private int id;
private String name;
private Address address;
//setters and getters
void displayInfo(){
System.out.println(id+" "+name);
System.out.println(address);
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="address1" class="com.javatpoint.Address">
<property name="addressLine1" value="51,Lohianagar"></property>
<property name="city" value="Ghaziabad"></property>
<property name="state" value="UP"></property>
<property name="country" value="India"></property>
</bean>
<bean id="obj" class="com.javatpoint.Employee">
<property name="id" value="1"></property>
<property name="name" value="Sachin Yadav"></property>
<property name="address" ref="address1"></property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Employee e=(Employee)factory.getBean("obj");
e.displayInfo();
}
}
6.11 通過Setter注入集合類型
Questions.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.List;
public class Question {
private int id;
private String name;
private List<String> answers;
//setters and getters
public void displayInfo(){
System.out.println(id+" "+name);
System.out.println("answers are:");
Iterator<String> itr=answers.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="q" class="com.javatpoint.Question">
<property name="id" value="1"></property>
<property name="name" value="What is Java?"></property>
<property name="answers">
<list>
<value>Java is a programming language</value>
<value>Java is a platform</value>
<value>Java is an Island</value>
</list>
</property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.12 通過Setter注入獨立對象
Questions.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.List;
public class Question {
private int id;
private String name;
private List<Answer> answers;
//setters and getters
public void displayInfo(){
System.out.println(id+" "+name);
System.out.println("answers are:");
Iterator<Answer> itr=answers.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Answer.java:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="answer1" class="com.javatpoint.Answer">
<property name="id" value="1"></property>
<property name="name" value="Java is a programming language"></property>
<property name="by" value="Ravi Malik"></property>
</bean>
<bean id="answer2" class="com.javatpoint.Answer">
<property name="id" value="2"></property>
<property name="name" value="Java is a platform"></property>
<property name="by" value="Sachin"></property>
</bean>
<bean id="q" class="com.javatpoint.Question">
<property name="id" value="1"></property>
<property name="name" value="What is Java?"></property>
<property name="answers">
<list>
<ref bean="answer1"/>
<ref bean="answer2"/>
</list>
</property>
</bean>
</beans>
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="answer1" class="com.javatpoint.Answer">
<property name="id" value="1"></property>
<property name="name" value="Java is a programming language"></property>
<property name="by" value="Ravi Malik"></property>
</bean>
<bean id="answer2" class="com.javatpoint.Answer">
<property name="id" value="2"></property>
<property name="name" value="Java is a platform"></property>
<property name="by" value="Sachin"></property>
</bean>
<bean id="q" class="com.javatpoint.Question">
<property name="id" value="1"></property>
<property name="name" value="What is Java?"></property>
<property name="answers">
<list>
<ref bean="answer1"/>
<ref bean="answer2"/>
</list>
</property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.13 通過Setter注入非對象Map
Questions.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class Question {
private int id;
private String name;
private Map<String,String> answers;
//getters and setters
public void displayInfo(){
System.out.println("question id:"+id);
System.out.println("question name:"+name);
System.out.println("Answers....");
Set<Entry<String, String>> set=answers.entrySet();
Iterator<Entry<String, String>> itr=set.iterator();
while(itr.hasNext()){
Entry<String,String> entry=itr.next();
System.out.println("Answer:"+entry.getKey()+" Posted By:"+entry.getValue());
}
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="q" class="com.javatpoint.Question">
<property name="id" value="1"></property>
<property name="name" value="What is Java?"></property>
<property name="answers">
<map>
<entry key="Java is a programming language" value="Sonoo Jaiswal"></entry>
<entry key="Java is a Platform" value="Sachin Yadav"></entry>
</map>
</property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.14 通過Setter注入對象Map
Questions.java:
package com.javatpoint;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class Question {
private int id;
private String name;
private Map<Answer,User> answers;
//getters and setters
public void displayInfo(){
System.out.println("question id:"+id);
System.out.println("question name:"+name);
System.out.println("Answers....");
Set<Entry<Answer, User>> set=answers.entrySet();
Iterator<Entry<Answer, User>> itr=set.iterator();
while(itr.hasNext()){
Entry<Answer, User> entry=itr.next();
Answer ans=entry.getKey();
User user=entry.getValue();
System.out.println("Answer Information:");
System.out.println(ans);
System.out.println("Posted By:");
System.out.println(user);
}
}
}
Answer.java:
package com.javatpoint;
import java.util.Date;
public class Answer {
private int id;
private String answer;
private Date postedDate;
public Answer() {}
public Answer(int id, String answer, Date postedDate) {
super();
this.id = id;
this.answer = answer;
this.postedDate = postedDate;
}
public String toString(){
return "Id:"+id+" Answer:"+answer+" Posted Date:"+postedDate;
}
}
User.java:
package com.javatpoint;
public class User {
private int id;
private String name,email;
public User() {}
public User(int id, String name, String email) {
super();
this.id = id;
this.name = name;
this.email = email;
}
public String toString(){
return "Id:"+id+" Name:"+name+" Email Id:"+email;
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="answer1" class="com.javatpoint.Answer">
<property name="id" value="1"></property>
<property name="answer" value="Java is a Programming Language"></property>
<property name="postedDate" value="12/12/2001"></property>
</bean>
<bean id="answer2" class="com.javatpoint.Answer">
<property name="id" value="2"></property>
<property name="answer" value="Java is a Platform"></property>
<property name="postedDate" value="12/12/2003"></property>
</bean>
<bean id="user1" class="com.javatpoint.User">
<property name="id" value="1"></property>
<property name="name" value="Arun Kumar"></property>
<property name="email" value="arun@gmail.com"></property>
</bean>
<bean id="user2" class="com.javatpoint.User">
<property name="id" value="2"></property>
<property name="name" value="Varun Kumar"></property>
<property name="email" value="Varun@gmail.com"></property>
</bean>
<bean id="q" class="com.javatpoint.Question">
<property name="id" value="1"></property>
<property name="name" value="What is Java?"></property>
<property name="answers">
<map>
<entry key-ref="answer1" value-ref="user1"></entry>
<entry key-ref="answer2" value-ref="user2"></entry>
</map>
</property>
</bean>
</beans>
Test.java:
package com.javatpoint;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Test {
public static void main(String[] args) {
Resource r=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(r);
Question q=(Question)factory.getBean("q");
q.displayInfo();
}
}
6.15 通過Autowire注入
Autowire可以隱式注入依賴:
- 內部使用Setter注入
- 內部使用構造器注入
Autowire:
- 寫更少的代碼
- 不被程序員控制
- 不能作用于基礎類型和字符串
Autowire的模式:
- no
- byName
通過bean的名字注入bean赘风,屬性名和bean名必須相同邀窃,調用的是setter注入 - byType
通過類型注入瞬捕,屬性名和bean名可以不同肪虎,通過setter注入 - constructor
通過調用構造器注入
Autowire的例子如下扇救。
B.java:
package org.sssit;
public class B {
B(){System.out.println("b is created");}
void print(){System.out.println("hello b");}
}
A.java:
package org.sssit;
public class A {
B b;
A(){System.out.println("a is created");}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
void print(){System.out.println("hello a");}
void display(){
print();
b.print();
}
}
A依賴B爵政。
appliactoin.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd">
<bean id="b" class="org.sssit.B"></bean>
<bean id="a" class="org.sssit.A" autowire="byName"></bean>
</beans>
Test.java:
package org.sssit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
A a=context.getBean("a",A.class);
a.display();
}
}
- 通過byName方式注入洁灵,這種方式必須屬性名與bean名相同:
<bean id="b" class="org.sssit.B"></bean>
<bean id="a" class="org.sssit.A" autowire="byName"></bean>
A中B依賴的屬性名為b徽千,與bean的id相同
- 通過byType方式注入双抽,這種方式不必屬性名與bean名相同牍汹,但相同類型bean只能有一個:
<bean id="b1" class="org.sssit.B"></bean>
<bean id="a" class="org.sssit.A" autowire="byType"></bean>
此時只有一個B類bean,在a的bean初始化的時候锨并,當發(fā)現(xiàn)缺失b依賴第煮,會自動到容器中尋找同類型的bean包警,此時這種類型的bean只有b1一個,b1被自動注入
<bean id="b1" class="org.sssit.B"></bean>
<bean id="b2" class="org.sssit.B"></bean>
<bean id="a" class="org.sssit.A" autowire="byType"></bean>
此時有兩個B類bean篱瞎,當發(fā)現(xiàn)缺失b依賴俐筋,會自動到容器中尋找同類型的bean澄者,此時這種類型的bean只b1粱挡、b2兩個询筏,拋出異常
- 通過constructor注入:
<bean id="b" class="org.sssit.B"></bean>
<bean id="a" class="org.sssit.A" autowire="constructor"></bean>
如果有多個參數的構造器,最多參數的構造器將會被調用
6.16 通過工廠方法注入
省略踱讨。
7 Spring AOP
AOP是對OOP的補充:AOP也提供了模塊化痹筛。但模塊化的關鍵點是切面而不是類帚稠。
AOP將程序分成獨立的部分(稱為關注點)蔓挖,通過橫切關注點(cross-cutting concerns)來提高模塊化瘟判。
橫切關注點是可以影響整個程序拷获,應該被集中放在一處代碼的關注點。如事務管理驮吱,授權認證左冬,日志記錄拇砰,安全等。
假設需要在很多不同的方法中加入相同的關注點瑰枫,如果不用AOP剖毯,編寫和維護這些方法會造成很多問題擂达。
使用AOP板鬓,就不需要在這些方法中調用關注點的方法后德,而將關注點統(tǒng)一在一個類中維護抄腔,通過XML賦予條目绵患。如果日后這些方法中不需要關注點,只需要在XML中修改就可以達成目的筏勒。
7.1 AOP概念和術語
- Join point:加入點可以是程序中的任意點,有方法執(zhí)行病瞳,異常處理,字段訪問等逗柴。Spring只支持方法執(zhí)行加入點。
-
Advice:Advice表示一個切面在特定join point的操作屠尊,有以下幾種類型:
- Before Advice:在join point執(zhí)行之前執(zhí)行
- After Retunring Advice:在join point正常結束才會執(zhí)行
- After Throwing Advice:如果方法拋出異常才會執(zhí)行
- After(finally) Advice:不管方法執(zhí)行是否拋出異常,都會執(zhí)行的Advice
- Around Advice:在join point之前或之后執(zhí)行
- Pointcut:AOP與加入點相匹配的表達式語言
- Introduction:
- Target Object:
- Aspect:一個包含advices,join points的類
- Interceptor:一個只包含advice的切面
- AOP Proxy:實現(xiàn)切面合約
- Weaving:連接切面和應用程序種類或對象赃绊,以創(chuàng)建adviced object
AOP的實現(xiàn)有:
- AspectJ
- Spring AOP
- Spring 1.2 Old Style(dtd)
- AspectJ annotation-style
- Spring XML configuration-style(schema based)
- JBoss AOP
7.2
Spring 1.2 old style aop advices:
- Aefore Advice
- After Advice
- Around Advice
- Throws Advice
advice層次結構如下:
- advice
- Before Advice
- MethodBeforeAdvice
- After Advice
- AfterRunningAdvice
- ThrowsAdvice
- Inteceptor
- MethodInteceptor
- Before Advice
參考文章: