Spring框架基础
1 什么是Spring框架?
Spring框架是框架的框架,因为其提供了对如Structs,Hibernate,等框架的支持,应用Spring框架可以解决不同的技术上的问题(开发网页应用?)。
Spring框架的优势:
- 预定义了许多模板。
封装了JDBC,Hibernate,JPA等许多模板。让我们无需了解其具体技术细节就可以很轻松的使用它们。 - 代码松耦合。
由依赖注入提供。 - 易于测试
也是因为依赖注入的特性 - 轻量级
由于POJO的存在,Spring框架不需要程序员继承任何类或者接口。 - 快速部署
因为Spring框架支持不同的框架,这使得它很容易开发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
提供:类检测、实现类加载器
- Aspects
- Data Access / Integration(数据访问与集成)
与数据库交互- JDBC
- ORM
- OXM
- JMS
- Transaction
- Web (MVC / Remoting)
创建Web应用- Web
- Web-Servlet
- Web-Struts
- Web-Portlet
- Core & Beans
3 Spring控制反转和依赖注入的一个小例子
控制反转和依赖注入:消除代码中的依赖关系。
Spring使用控制反转和依赖注入来使程序达到松耦合的目的。
看一个小例子:
class Employee{
Address address;
Employee(){
address=new Address();
}
}
这个例子中,职员类依赖了地址类。创建职员类时,先要创建地址类。
class Employee{
Address address;
Employee(Address address){
this.address=address;
}
}
这个例子中,创建职员类时,由外部传入地址类,不用再在职员类中创建,实现了代码的松耦合。
4 Spring应用的一个小例子
用你喜欢的ide(或者不用ide)创建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);
}
}
创建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>
创建测试类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创建一个beanFactory
- 从beanFactory中获取在xml中定义好的bean "studentbean"
5 Spring IoC容器
IoC容器的功能:
- 实例化类
- 配置对象
- 组装对象间的依赖
IoC容器从XML文件获取信息并根据信息进行工作。
IoC容器类型有两种:
- BeanFactory
- ApplicationContext
两种IoC容器的区别:
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注入
两种注入方式的区别:
- 部分依赖注入只能通过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使用传统方式构造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初始化的时候,当发现缺失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,当发现缺失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,就不需要在这些方法中调用关注点的方法,而将关注点统一在一个类中维护,通过XML赋予条目。如果日后这些方法中不需要关注点,只需要在XML中修改就可以达成目的。
7.1 AOP概念和术语
- Join point:加入点可以是程序中的任意点,有方法执行,异常处理,字段访问等。Spring只支持方法执行加入点。
-
Advice:Advice表示一个切面在特定join point的操作,有以下几种类型:
- Before Advice:在join point执行之前执行
- After Retunring Advice:在join point正常结束才会执行
- After Throwing Advice:如果方法抛出异常才会执行
- After(finally) Advice:不管方法执行是否抛出异常,都会执行的Advice
- Around Advice:在join point之前或之后执行
- Pointcut:AOP与加入点相匹配的表达式语言
- Introduction:
- Target Object:
- Aspect:一个包含advices,join points的类
- Interceptor:一个只包含advice的切面
- AOP Proxy:实现切面合约
- Weaving:连接切面和应用程序种类或对象,以创建adviced object
AOP的实现有:
- 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
参考文章: