1、spring
源码地址:https://repo.spring.io/libs-release-local/org/springframework/
2、配置
Person类
package com.mashibing.spring;
public class Person {
private String name;
private int age;
private Food food;
public Person(String name, int age, Food food) {
super();
this.name = name;
this.age = age;
this.food = food;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
}
Food类
package com.mashibing.spring;
public class Food {
private String name;
public Food(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Food [name=" + 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"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "person" class = "com.mashibing.spring.Person">
<constructor-arg name="name" value="maxiaosan"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="food" ref="food"></constructor-arg>
</bean>
<bean id="food" class="com.mashibing.spring.Food">
<constructor-arg name="name" value="香蕉"></constructor-arg>
</bean>
</beans>
TestGetBean类
package com.mashibing.spring;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestGetBean {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = ctx.getBean("person",Person.class);
//Food food = ctx.getBean("food",Food.class);
// food.setName("香蕉");
// person.setName("zhangsan");
// person.setAge(18);
// person.setFood(food);
//和复写实体类中得toString方法一样,需要依赖common-lang包 /01SpringHelloWorld/libs/commons-lang3-3.9.jar
System.out.println(ToStringBuilder.reflectionToString(person, ToStringStyle.MULTI_LINE_STYLE));
}
}
3、基于XML的DI
解析applicationContext.xml
并不是所有都会在联网情况下找xsd文件。
1 <?xml version = "1.0" encoding = "UTF-8"?>
2 <beans xmlns = "http://www.springframework.org/schema/beans"
3 xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation = "http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
6 </beans>
2 <beans xmlns = "http://www.springframework.org/schema/beans" ns-namespace 只是表示一个id和类名上的包名一样
PluggableSchemaResolver这个类会去加载.xsd文件
PluggableSchemaResolver源码:
1 /*
2 * Copyright 2002-2019 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.beans.factory.xml;
18
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.util.Map;
22 import java.util.Properties;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.xml.sax.EntityResolver;
28 import org.xml.sax.InputSource;
29
30 import org.springframework.core.io.ClassPathResource;
31 import org.springframework.core.io.Resource;
32 import org.springframework.core.io.support.PropertiesLoaderUtils;
33 import org.springframework.lang.Nullable;
34 import org.springframework.util.Assert;
35 import org.springframework.util.CollectionUtils;
36
37 /**
38 * {@link EntityResolver} implementation that attempts to resolve schema URLs into
39 * local {@link ClassPathResource classpath resources} using a set of mappings files.
40 *
41 * <p>By default, this class will look for mapping files in the classpath using the
42 * pattern: {@code META-INF/spring.schemas} allowing for multiple files to exist on
43 * the classpath at any one time.
44 *
45 * <p>The format of {@code META-INF/spring.schemas} is a properties file where each line
46 * should be of the form {@code systemId=schema-location} where {@code schema-location}
47 * should also be a schema file in the classpath. Since {@code systemId} is commonly a
48 * URL, one must be careful to escape any ':' characters which are treated as delimiters
49 * in properties files.
50 *
51 * <p>The pattern for the mapping files can be overridden using the
52 * {@link #PluggableSchemaResolver(ClassLoader, String)} constructor.
53 *
54 * @author Rob Harrop
55 * @author Juergen Hoeller
56 * @since 2.0
57 */
58 public class PluggableSchemaResolver implements EntityResolver {
59
60 /**
61 * The location of the file that defines schema mappings.
62 * Can be present in multiple JAR files.
63 */
64 public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";
65
66
67 private static final Log logger = LogFactory.getLog(PluggableSchemaResolver.class);
68
69 @Nullable
70 private final ClassLoader classLoader;
71
72 private final String schemaMappingsLocation;
73
74 /** Stores the mapping of schema URL -> local schema path. */
75 @Nullable
76 private volatile Map<String, String> schemaMappings;
77
78
79 /**
80 * Loads the schema URL -> schema file location mappings using the default
81 * mapping file pattern "META-INF/spring.schemas".
82 * @param classLoader the ClassLoader to use for loading
83 * (can be {@code null}) to use the default ClassLoader)
84 * @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
85 */
86 public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
87 this.classLoader = classLoader;
88 this.schemaMappingsLocation = DEFAULT_SCHEMA_MAPPINGS_LOCATION;
89 }
90
91 /**
92 * Loads the schema URL -> schema file location mappings using the given
93 * mapping file pattern.
94 * @param classLoader the ClassLoader to use for loading
95 * (can be {@code null}) to use the default ClassLoader)
96 * @param schemaMappingsLocation the location of the file that defines schema mappings
97 * (must not be empty)
98 * @see PropertiesLoaderUtils#loadAllProperties(String, ClassLoader)
99 */
100 public PluggableSchemaResolver(@Nullable ClassLoader classLoader, String schemaMappingsLocation) {
101 Assert.hasText(schemaMappingsLocation, "'schemaMappingsLocation' must not be empty");
102 this.classLoader = classLoader;
103 this.schemaMappingsLocation = schemaMappingsLocation;
104 }
105
106
107 @Override
108 @Nullable
109 public InputSource resolveEntity(@Nullable String publicId, @Nullable String systemId) throws IOException {
110 if (logger.isTraceEnabled()) {
111 logger.trace("Trying to resolve XML entity with public id [" + publicId +
112 "] and system id [" + systemId + "]");
113 }
114
115 if (systemId != null) {
116 String resourceLocation = getSchemaMappings().get(systemId);
117 if (resourceLocation == null && systemId.startsWith("https:")) {
118 // Retrieve canonical http schema mapping even for https declaration
119 resourceLocation = getSchemaMappings().get("http:" + systemId.substring(6));
120 }
121 if (resourceLocation != null) {
122 Resource resource = new ClassPathResource(resourceLocation, this.classLoader);
123 try {
124 InputSource source = new InputSource(resource.getInputStream());
125 source.setPublicId(publicId);
126 source.setSystemId(systemId);
127 if (logger.isTraceEnabled()) {
128 logger.trace("Found XML schema [" + systemId + "] in classpath: " + resourceLocation);
129 }
130 return source;
131 }
132 catch (FileNotFoundException ex) {
133 if (logger.isDebugEnabled()) {
134 logger.debug("Could not find XML schema [" + systemId + "]: " + resource, ex);
135 }
136 }
137 }
138 }
139
140 // Fall back to the parser's default behavior.
141 return null;
142 }
143
144 /**
145 * Load the specified schema mappings lazily.
146 */
147 private Map<String, String> getSchemaMappings() {
148 Map<String, String> schemaMappings = this.schemaMappings;
149 if (schemaMappings == null) {
150 synchronized (this) {
151 schemaMappings = this.schemaMappings;
152 if (schemaMappings == null) {
153 if (logger.isTraceEnabled()) {
154 logger.trace("Loading schema mappings from [" + this.schemaMappingsLocation + "]");
155 }
156 try {
157 Properties mappings =
158 PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
159 if (logger.isTraceEnabled()) {
160 logger.trace("Loaded schema mappings: " + mappings);
161 }
162 schemaMappings = new ConcurrentHashMap<>(mappings.size());
163 CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
164 this.schemaMappings = schemaMappings;
165 }
166 catch (IOException ex) {
167 throw new IllegalStateException(
168 "Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex);
169 }
170 }
171 }
172 }
173 return schemaMappings;
174 }
175
176
177 @Override
178 public String toString() {
179 return "EntityResolver using schema mappings " + getSchemaMappings();
180 }
181
182 }
引入多个配置文件:
id和name都可以标记bean
4、不用构造器的属性注入
启动程序报上面错误,说明Person对象必须有无参构造器。
加一段:xmlns:p=http://www.springframework.org/schema/p
<bean id="person" class="com.msb.Person" p:age="21" p:name="zhangsan" p:food-ref = "food">
5、Properties
Person类
1 package com.mashibing.spring; 2 3 import java.util.Properties; 4 5 public class Person { 6 7 public Person() { 8 super(); 9 } 10 private String name; 11 private int age; 12 private Food food; 13 14 private Properties gift; 15 16 17 public Person(String name, int age, Food food) { 18 super(); 19 this.name = name; 20 this.age = age; 21 this.food = food; 22 } 23 24 25 public Properties getGift() { 26 return gift; 27 } 28 29 30 public void setGift(Properties gift) { 31 this.gift = gift; 32 } 33 34 35 public String getName() { 36 return name; 37 } 38 public void setName(String name) { 39 this.name = name; 40 } 41 public int getAge() { 42 return age; 43 } 44 public void setAge(int age) { 45 this.age = age; 46 } 47 public Food getFood() { 48 return food; 49 } 50 public void setFood(Food food) { 51 this.food = food; 52 } 53 54 55 }
Person类:
application.xml中
6、作用域
spring中的get出来的默认都是单例的。
spring为bean提供了6个作用域:singleton、prototype、websocket、request、session、application都是单例的
prototype:
7、关于Spring
为什么用单例?
性能问题。
单例在并发场景下有没有问题?
有。在单例类里面不能有状态数据,如果有要非常小心
线程的连接和关闭都放到ThreadLocal里面进行隔离。
8、延迟加载
lazy-init="true"懒加载
9、工厂类
Car接口:
package com.mashibing.spring; public interface Car { public String getName(); public String getPrice(); }
Audi实现类:
package com.mashibing.spring; public class Audi implements Car { @Override public String getName() { return "我是奥迪A7"; } @Override public String getPrice() { return "700000"; } }
Bmw实现类:
package com.mashibing.spring; public class Bmw implements Car { @Override public String getName() { return "BMW 7"; } @Override public String getPrice() { return "700000"; } }
工厂CarFactory类:
package com.mashibing.spring; /** * 简单工厂 * @author 14308 * */ public class CarFactory { public Car getCar(String name) throws Exception{ if (name.equals("audi")) { return new Audi(); } else { throw new Exception("暂时没法生产这辆车"); } } }
Test类:
疑问???如果是web项目那么每次要修改参数都要在程序中修改一次。
下面用bean工厂的方式创建
动态工厂创建:
<?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-3.0.xsd">
<bean id="carFactory" class="com.mashibing.spring.CarFactory"/>
<bean id="car" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="audi"></constructor-arg>
</bean>
</beans>