【笔记】Spring入门篇(一)了解spring
24903
本文是我的「Spring学习笔记」第一篇,具体内容可见右侧内容概要,【本文长期更新】。
1、HelloWorld程序
注:导入Jar包(commons-logging.jar 和spring.jar)
1.1HelloWorld.java
package com.wq.createobject; public class HelloWorld { public void sayHello(){ System.out.println("Hello wuqingvika"); } }
|
1.2applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="HelloWorld" class="com.wq.createobject.HelloWorld"></bean> </beans>
|
1.3HelloWorldTest.java
package com.xzit.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.wq.createobject.HelloWorld; import junit.framework.TestCase; public class HelloWorldTest extends TestCase { @Test public void testHelloWorld(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld"); wq.sayHello(); } }
|
2、Spring创建对象的方式
2.1默认的构造函数创建对象
public class HelloWorld { public HelloWorld(){ System.out.println("hello wucan"); } public void sayHello(){ System.out.println("Hello wuqingvika"); } }
|
<!-- 第1种方式 --> <bean id="HelloWorld" class="com.wq.createobject.method.HelloWorld"></bean>
|
@Test public void testHelloWorld_Default(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld"); wq.sayHello(); }
|
2.2利用静态工厂模式创建对象
package com.wq.createobject.method.factory; import com.wq.createobject.method.HelloWorld; public class HelloWorldFactory { public static HelloWorld getInstance(){ return new HelloWorld(); } }
|
<!-- 第2种方式 --> <bean id="helloWorld2" class="com.wq.createobject.method.factory.HelloWorldFactory" factory-method="getInstance"></bean>
|
@Test public void testHelloWorldFactory(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("helloWorld2"); wq.sayHello(); }
|
2.3实例工厂方法
package com.wq.createobject.method.factory; import com.wq.createobject.method.HelloWorld; public class HelloWorldFactory2 { public HelloWorld getInstance(){ return new HelloWorld(); } }
|
<!-- 第3种方式 wqwqwq--> <bean id="helloWorldFactory" class="com.wq.createobject.method.factory.HelloWorldFactory2" ></bean> <!-- factory-bean是一个工厂bean factory-method是一个工厂方法 --> <bean id="helloWorld3" factory-bean="helloWorldFactory" factory-method="getInstance"></bean>
|
@Test public void testCreateObject_InstaceFactory(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld3"); helloWorld.sayHello(); }
|
3、Spring别名
3.1HelloWorld.java
package com.wq.alias; public class HelloWorld { public void sayHello(){ System.out.println("Hello wuqingvika"); } }
|
3.2配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="HelloWorld" class="com.wq.alias.HelloWorld"></bean> <!--name要与id对应哦--> <alias name="HelloWorld" alias="吴大大"/> <alias name="HelloWorld" alias="吴小小"/> </beans>
|
3.3测试方法
public void testHelloWorld(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld"); wq.sayHello(); HelloWorld wq1=(HelloWorld)context.getBean("吴大大"); wq1.sayHello(); HelloWorld wq2=(HelloWorld)context.getBean("吴小小"); wq2.sayHello(); }
|
4、Spring创建对象的时间
知识点:
在默认情况下启动Spring容器的时候创建对象。
配置文件
<bean id="helloWorld" class="com.itheima12.spring.createobject.when.HelloWorld"></bean> <bean id="helloWorld2" class="com.itheima12.spring.createobject.when.HelloWorld" lazy-init="true"></bean>
@Test public void testHelloWorld_Default(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld"); helloWorld.hello(); }
@Test public void testHelloWorld_Lazy_init_TRUE(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld"); HelloWorld helloWorld2 = (HelloWorld)context.getBean("helloWorld2"); helloWorld.hello(); }
|
5、单例与多例
5.1单例
配置文件
<bean id="HelloWorld" class="com.wq.scope.HelloWorld"></bean>`
* 在spring容器中的对象,默认情况下是单例的 * 因为对象是单例的,所以只要在类上声明一个属性,该属性中含有数据, * 那么该属性是全局的(很危险) *============(输出结果)============= * 这是无参构造方法哟 * com.wq.scope.HelloWorld@7cdbc5d3 * com.wq.scope.HelloWorld@7cdbc5d3 *==================================== */ @Test public void testHelloWorld_default(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld"); HelloWorld wq1=(HelloWorld)context.getBean("HelloWorld"); System.out.println(wq); System.out.println(wq1); }
|
5.2多例
配置文件
<bean id="HelloWorld2" class="com.wq.scope.HelloWorld" scope="prototype"></bean>
|
测试方法
@Test public void testHelloWorld_scope_prototype(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld2"); HelloWorld wq1=(HelloWorld)context.getBean("HelloWorld2"); System.out.println(wq); System.out.println(wq1); }
|
6、Springday的init和destroy和执行流程
测试方法
@Test public void testHelloWorld_default(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld wq=(HelloWorld)context.getBean("HelloWorld"); wq.sayHello(); ClassPathXmlApplicationContext contextwq=(ClassPathXmlApplicationContext)context; contextwq.close(); }
|
配置文件
<bean id="HelloWorld" class="com.wq.scope.HelloWorld" init-method="init" destroy-method="destory"></bean>
|
执行流程
1、创建一个spring容器的对象
2、调用构造函数创建在spring容器中的对象(不能是多实例的,lazy-init不能为true)
3、执行一个对象的init方法
4、利用context.getBean得到一个对象,但是这个时候如果一个bean的scope为prototype或者lazy-init为true,则创建对象
5、对象调用业务逻辑方法
6、当Spring容器关闭的时候执行destory方法
7、spring容器的DI-xml-setter方法
7.1Student.java
package com.wq.di.xml.setter; public class Student { public void say(){ System.out.println("Student..."); } }
|
7.2Person.java
package com.wq.di.xml.setter;
import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;
public class Person { private Long pid; private String pname; private Student student; private List lists; private Set sets; private Map maps; private Properties properties; public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } private Object[] objects; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public List getLists() { return lists; } public void setLists(List lists) { this.lists = lists; } public Set getSets() { return sets; } public void setSets(Set sets) { this.sets = sets; } public Map getMaps() { return maps; } public void setMaps(Map maps) { this.maps = maps; } public Object[] getObjects() { return objects; } public void setObjects(Object[] objects) { this.objects = objects; } }
|
7.3配置文件
<bean id="person" class="com.wq.di.xml.setter.Person"> <!-- property就是一个bean的属性 name就是用来描述属性的名称 value就是值,如果是一般类型(基本类型和String) --> <property name="pid" value="20130501403"></property> <property name="pname" value="wuqingvika"></property> <!-- spring容器内部创建的student对象给Person的student对象赋值了 --> <property name="student" > <ref bean="student"/> </property> <property name="lists"> <list> <value>list1</value> <value>list2</value> </list> </property> <property name="sets"> <set> <value>set1</value> <value>set2</value> </set> </property> <property name="maps"> <map> <entry key="m1"> <value>map1</value> </entry> <entry key="m2"> <value>map2</value> </entry> </map> </property> <property name="properties"> <props> <prop key="p1">prop1</prop> <prop key="p2">prop2</prop> </props> </property> <property name="objects"> <list> <value>obj1</value> <ref bean="student"/> </list> </property> </bean> <bean id="student" class="com.wq.di.xml.setter.Student"></bean>
|
7.4测试方法
@Test public void testHelloWorld_di_xml_setter(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Person p=(Person)context.getBean("person"); System.out.println(p.getPname()+" "+p.getLists().size()); }
|
8、spring容器的IOC和DI的意义
最原始的用法
8.1Document.java(接口)
public interface Document { public void writeDocument(); public void readDocument(); }
|
8.2ExcelDocument.java(实现类)
public class ExcelDocument implements Document {
@Override public void writeDocument() { System.out.println("Excel Write"); }
@Override public void readDocument() { System.out.println("Excel read"); }
}
|
PdfDocument.java同上
WordDocument.java同上
8.3DocumentManager.java
public class DocumentManager { private Document document; public DocumentManager(Document document){ this.document=document; } public void readDocument(){ this.document.readDocument(); } public void writeDocument(){ this.document.writeDocument(); } }
|
8.4测试方法
//为不完全的面向接口编程
public class DocumentTest{ @Test public void testDocument_NoSpring(){ Document document=new WordDocument(); DocumentManager dm=new DocumentManager(document); dm.readDocument(); dm.writeDocument(); } }
|
输出结果
Word read
Word Write
8.5利用spring(DocumentManager.java)
public class DocumentManager { private Document document;
public void readDocument(){ this.document.readDocument(); } public Document getDocument() { return document; }
public void setDocument(Document document) { this.document = document; }
public void writeDocument(){ this.document.writeDocument(); } }
|
8.6applicationContext.xml
<bean id="documentManager" class="com.wq.spring.iocdi.DocumentManager"> <!-- 该属性是一个接口 --> <property name="document"> <ref bean="excelDocument"/> </property> </bean> <bean id="wordDocument" class="com.wq.spring.iocdi.WordDocument"></bean> <bean id="pdfDocument" class="com.wq.spring.iocdi.PdfDocument"></bean> <bean id="excelDocument" class="com.wq.spring.iocdi.ExcelDocument"></bean>
|
8.7测试方法
IOC和DI结合的真正的意义:java代码端完全的面向接口编程
@Test public void testDocument_Spring(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); DocumentManager dm=(DocumentManager) context.getBean("documentManager"); dm.writeDocument(); dm.readDocument(); }
|
9、spring容器的IOC和DI的意义-mvc
9.1PersonDao.java(接口)
public interface PersonDao { public void savePerson(); }
|
9.2PersonDaoImpl(实现类)
public class PersonDaoImpl implements PersonDao {
@Override public void savePerson() { System.out.println("save person hahahaha..."); } }
|
9.3PersonService
public interface PersonService { public void savePerson(); }
|
9.4PersonServiceImpl
public class PersonServiceImpl implements PersonService { private PersonDao personDao; public PersonDao getPersonDao() { return personDao; } public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } @Override public void savePerson() { this.personDao.savePerson(); } }
|
9.5PersonAction.java
public class PersonAciton { private PersonService personService;
public PersonService getPersonService() { return personService; }
public void setPersonService(PersonService personService) { this.personService = personService; } public void savePerson(){ this.personService.savePerson(); } }
|
9.6application.xml
<bean id="personDao" class="com.wq.spring.dao.impl.PersonDaoImpl"></bean> <bean id="personService" class="com.wq.spring.service.impl.PersonServiceImpl"> <property name="personDao"> <ref bean="personDao"/> </property> </bean> <bean id="personAction" class="com.wq.spring.action.PersonAciton"> <property name="personService"> <ref bean="personService"/> </property> </bean>
|
9.7测试类
public class MVCTest {
@Test public void testMvc(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); PersonAciton personAction=(PersonAciton)context.getBean("personAction"); personAction.savePerson(); } }
|
10、spring容器的DI-构造器注入
10.1Person.java
- 也可同时给出所有属性的set方法。(可以同时使用)
public class Person { private Long pid; private String pname; private Student student; private List lists; private Set sets; private Map maps; private Properties properties; public Person(){ } public Person(String pname) { super(); this.pname = pname; }
public Person(String pname, Student student) { super(); this.pname = pname; this.student = student; } public Long getPid() { return pid; } public String getPname() { return pname; } public Student getStudent() { return student; } public List getLists() { return lists; } public Set getSets() { return sets; } public Map getMaps() { return maps; } public Properties getProperties() { return properties; } }
|
10.2Student.java
public class Student { public void say(){ System.out.println("Student..."); } }
|
10.3applicationContext.xml
<bean id="person" class="com.wq.di.xml.constructor.Person"> <!-- constructor-arg指的是构造器中的参数 index 角标 从0开始 value 如果一般类型,用value赋值 ref 引用类型赋值 --> <constructor-arg index="0" value="wuqingvika"> </constructor-arg> <constructor-arg index="1" ref="student"></constructor-arg> </bean> <bean id="student" class="com.wq.di.xml.constructor.Student"></bean>
|
10.4测试方法
@Test public void testHelloWorld_di_xml_constructor(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Person p=(Person)context.getBean("person"); System.out.println(p.getPname()); p.getStudent().say(); }
|
11、spring容器的继承
11.1Person.java(父类)
public class Person { private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
11.2Student.java(子类)
public class Student extends Person {
}
|
11.3applicationContext.xml
第一种方式
<!--在父类中进行赋值,子类通过parent属性继承父类的内容--> <bean id="person" class="com.wq.spring.extend.Person"> <property name="name" value="wuqing"></property> </bean> <!--parent 实现了spring容器内部的继承关系--> <bean id="student" class="com.wq.spring.extend.Student" parent="person"></bean>
|
第二种方式
<!-- 因为java的继承机制,子类继承了父类的setXxx方法,所以子类可以利用setXxx方法注入值 --> <bean id="person2" class="com.wq.spring.extend.Person"></bean> <bean id="student2" class="com.wq.spring.extend.Student"> <property name="name" value="wuqing2"></property> </bean>
|
11.4测试方法
@Test public void testExtends(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); Student st=(Student) context.getBean("student2"); System.out.println(st.getName()); }
|
12、spring容器的注解
12.1ClassInfo.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ClassInfo { String name() default ""; }
|
12.2MethodInfo.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MethodInfo { String name() default ""; }
|
12.3Wuqingvika07Wu.java
@ClassInfo(name="这就是传说中的07Wu") public class Wuqingvika07Wu { @MethodInfo(name="传说中的Java学科") public void Java(){ } }
|
12.4AnnotationParse.java
import java.lang.reflect.Method; import org.junit.Test;
public class AnnotationParse {
public static void parse(){ Class class1= Wuqingvika07Wu.class; if(class1.isAnnotationPresent(ClassInfo.class)){ ClassInfo classInfo=(ClassInfo) class1.getAnnotation(ClassInfo.class); System.out.println(classInfo.name()); } Method[] methods= class1.getMethods(); for (Method method : methods) { if(method.isAnnotationPresent(MethodInfo.class)){ MethodInfo methodInfo=method.getAnnotation(MethodInfo.class); System.out.println(methodInfo.name()); } } } @Test public void testAnnotation(){ AnnotationParse.parse(); } }
|
输出结果
这就是传说中的07Wu
传说中的Java学科
13、spring容器的依赖注入的注解
注意:
@Resource用到,先在项目中AddLibrary->
MYEclipseLibraries->JavaEE5Libraries!!!
需要在配置文件applicationContext.xml中加入:
xmlns:context=”http://www.springframework.org/schema/context“
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
注解写法比较简单,但是效率比较低
13.1Student.java
public class Student { public void say(){ System.out.println("Student..."); } }
|
13.2Person.java
import javax.annotation.Resource;
public class Person {
@Resource(name="student")
private Student student;
public Student getStudent() { return student; }
public void setStudent(Student student) { this.student = student; } }
|
13.3applicationContext.xml
<bean id="person" class="com.wq.di.annotation.Person"></bean> <bean id="student" class="com.wq.di.annotation.Student"></bean> <!-- 启动依赖注入的注解解析器 --> <context:annotation-config></context:annotation-config>
|
13.4测试类
public class AnnotationTest extends TestCase { @Test public void testHelloWorld_di_annotation(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Person p=(Person)context.getBean("person"); p.getStudent().say(); } }
|
14、spring容器的类扫描注解
14.1Student.java
import org.springframework.stereotype.Component; @Component("student") public class Student { public void say(){ System.out.println("Student..."); } }
|
14.2Person.java
@Component("person") public class Person { @Resource(name="student") private Student student;
public Student getStudent() { return student; }
public void setStudent(Student student) { this.student = student; } }
|
14.3applicationContext.xml
<!-- component:把一个类放入到spring容器中,该类就是一个component 在base-package指定的包及子包下扫描所有的类 --> <context:component-scan base-package="com.wq.di.scan"></context:component-scan>
|
14.4测试类
1、启动spring容器,spring容器解析配置文件
2、当解析到
<context:component-scan base-package="com.wq.di.scan"> </context:component-scan>
|
就会在上面指定的包及子包中扫描所有的类,看哪些类上面有@Component注解
3、如果有该注解,则有如下的规则:
@Component public class PersonDaoImpl{ } == <bean id="personDaoImpl" class"..."/> id的值:把类的第一个字母变成小写,其他字母不变 @Component("personDao") public class PersonDaoImpl{ } <bean id="personDao" class=".."/>
|
4、按照@Resource注解的规则进行赋值*/
public class ScanTest extends TestCase { @Test public void testHelloWorld_di_scan(){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); Person p=(Person)context.getBean("person"); p.getStudent().say(); } }
|
15、spring容器的类扫描实现document
15.1DocumentManager.java
@Component("documentManager") public class DocumentManager { @Resource(name="wordDocument") private Document document; public void readDocument(){ this.document.readDocument(); }
public void writeDocument(){ this.document.writeDocument(); } }
|
15.2WordDucument.java
@Component("wordDocument") public class WordDocument implements Document { @Override public void writeDocument() { System.out.println("Word Write"); }
@Override public void readDocument() { System.out.println("Word read"); } }
|
PdfDocument.java和ExcelDocument.java同理。
15.3applicationContext.xml
<context:component-scan base-package="com.wq.spring.iocdi"></context:component-scan> ```
>注意:base-package为要扫描的类的包名。
15.4测试方法 -------- ```java @Test public void testDocument_Spring(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); DocumentManager dm=(DocumentManager) context.getBean("documentManager"); dm.writeDocument(); dm.readDocument(); }
|
16、spring容器的类扫描实现mvc
16.1配置文件
<context:component-scan base-package="com.wq.spring"></context:component-scan>
|
16.2PersonDao.java(接口)
package com.wq.spring.dao;
public interface PersonDao { public void savePerson(); }
|
16.3PersonDaoImpl.java(实现类)
@Repository("personDao") public class PersonDaoImpl implements PersonDao {
@Override public void savePerson() { System.out.println("save person wqhahahaha..."); } }
|
16.4PersonService.java(接口)
package com.wq.spring.service;
public interface PersonService { public void savePerson(); }
|
16.5PersonServiceImpl.java(实现)
@Service("personService") public class PersonServiceImpl implements PersonService { @Resource private PersonDao personDao; public PersonDao getPersonDao() { return personDao; }
public void setPersonDao(PersonDao personDao) { this.personDao = personDao; }
@Override public void savePerson() { this.personDao.savePerson(); }
}
|
16.6PersonAction.java
@Controller("personAction") @Scope("prototype") public class PersonAciton { @Resource(name="personService") private PersonService personService;
public void savePerson(){ this.personService.savePerson(); } }
|
16.7测试类
public class MVCTest {
@Test public void testMvc(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); PersonAciton personAction=(PersonAciton)context.getBean("personAction"); personAction.savePerson(); } }
|