搞了java那么多年,还没搞过spring,或者说之前遇到的都是非spring产品,所以就没有刻意使用过或学习过。
为了偷懒些,还是毅然决定在新的项目中使用spring framework。
今天是第一天学习spring,希望之后能够坚持下去吧,也希望spring刻意带给我更多的惊喜。
顺着spring framework reference 文档,先是IOC容器
spring的配置方式
1 配置文件
例如
<bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean>
2 标注 例如:@Configuration
, @Bean, @Import,
@DependsOn
初始化容器
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
或者
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
或者
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
或者
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
3,4的区别在于classpath的前缀。就如字面意思。 你懂得。
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
获取多个配置
IOC的XML头部定义
<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
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
xml中bean的属性
class,name,scope,constructor arguments,properties,autowiring mode,lazy-initialization mode,initialization method,destruction method
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
基本的配置方式
其中,id是真正的xml定义的ID元素。
如果要用一些特殊的字符定义一个bean,或者引入其他的alias到bean,就需使用name定义,多个name定义,刻意使用,;和空格进行分隔。
<alias name="fromName" alias="toName"/>
一个基本的alias定义
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
这是一个初始化bean的例子,createInstance 是一个方法,这个写法起到的作用是在构建一个bean的时候,调用这个方法。这样就可以使用工厂模式,将该bean实例化。但需注意的是,该方法必须是静态的。
使用这种方法,也可以做其他的类得静态工厂做嵌套的方式初始化实例。 具体的不细谈了,搞过其他的IOC的都知道。
下面是我们熟悉的DI了
<bean id="foo" class="x.y.Foo"> <constructor-arg ref="bar"/> <constructor-arg ref="baz"/> </bean> <bean id="bar" class="x.y.Bar"/> <bean id="baz" class="x.y.Baz"/>
这个例子很简单了,bar和baz都是注入到foo的对象。这里需注意的是对象的类不能写错了,否则你的程序铁定报错。
如果上面那个例子没看懂的话,再来一个 更简单的
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean>
这回懂了吧?
有些东西我们没有必要全部写在配置中,就用标注代替了。
@ConstructorProperties({"years", "ultimateAnswer"})
上面是初始化2个变量。把变量的名称就用string的方式写进去了。注意这个标注的名字,是构造时用的
那如果要注入的不是构造类中的字段呢?
<property name="beanOne"><ref bean="anotherExampleBean"/></property>
那就用这种吧。ref是申明一个外部bean
destroy-method="close"
再来一个,close是一个方法,在销毁这个对象的时候,会调用这个方法。字面意思很明白了。如果还不懂,就去补补java基础吧。
<property name="properties"> <value> jdbc.driver.className=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb </value> </property>
这个是使用properties的例子。太简单,不解释
<bean id="theTargetBean" class="..."/> <bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean" /> </property> </bean>
看看这个例子。有一个idref的标签。
<property name="targetName" value="theTargetBean" />
其实这2个的写法都差不多。 第一个使用的idref,他会在部署时,检查该对象是否已存在,而第二种则是不管三七二十一给你创建了再说。各有利弊吧,看你怎么用了。用的好了,可以提高应用性能。用的不好了么,呵呵 顶多你到时候数据出错呗。反正还是一点,不能滥用。
再来点关于集合的。
<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setAdminEmails(java.util.Properties) call --> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean>
太简单,不解释。一看就明白了。
<null/>
补充一下,上文那一大坨的,可以加这个null标签。意思么 你懂得。
<bean id="beanOne" class="ExampleBean" depends-on="manager"/> <bean id="manager" class="ManagerBean" />
这个例子么,呵呵 depends-on和ref的功用其实是一样的,但是他们的运行方式和需求环境不同。在2个bean中存在弱直接关系的话,就必须要用到这个而不是使用ref。容器会在对象实例化之前将所需的对象给实例了。
一般不是很追求性能或无视性能的话,可以无视这个。但推荐与ref混搭。
lazy-init="true"
告诉IOC,在第一次访问该BEAN的时候实例了。而不是在启动的时候实例。
default-lazy-init="true"
或者使用这个在beans中添加,既为默认设定
今天先写那么多,明天继续。