一. 环境搭建(简单三步就能创建一个Spring框架)
- 创建一个动态web项目
- 将Spring开发包引入项目(包下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring/)
- 将Spring配置文件beans.xml拷贝到src下面(内容如下)
<?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.xsd"> </beans>
二. 利用Spring管理对象实例(下面用实际代码说明Spring怎样管理对象)
- 在beans.xml中添加需要管理的对象(添加在<bean>中)
<bean class="com.yuanhuan.helloworld.HelloWorld" id="helloWorld"/> <!--id为对象名-->
- 使用(在java代码中调用实例)
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); HelloWorld helloWorld = (HelloWorld) ac.getBean("helloWorld");
三. 简单理解Spring IOC(下面一个简单例子来说明对IOC的理解)
-
含义:IOC(控制反转:Inverse ofControl ),又称作 依赖注入,是一种重要的面向对象编程的法则来削减计算机程 序的耦合问题,也是轻量级的 Spring 框架的核心
-
举例:若主管每次要安排不同员工做测试,每个员工和主管都是一个类,所以每次都需要该大量的源代码,维护极其不方便,所以就可以用控制反转的方式(或者说依赖注入),通过Spring来管理对象实例,每次更改只需要修改配置文件(beans.xml)即可。
代码://lisi.java public class LiSi implements Worker { @Override public void test() { System.out.println("李四正在做测试"); } } //zhangsan.java public class ZhangSan implements Worker { @Override public void test() { System.out.println("张三正在做测试"); } } //worker.java public interface Worker { void test(); } //zhuguan.java public class ZhuGuan { Worker worker; public void setWorker(Worker worker) { this.worker = worker; } public void doTest() { worker.test(); } } //test.java public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); ZhuGuan zhuGuan = (ZhuGuan) ac.getBean("zhuGuan"); zhuGuan.doTest(); } } //beans.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.xsd"> <bean class="com.yuanhuan.service.LiSi" id="liSi"/> <bean class="com.yuanhuan.service.ZhangSan" id="zhangSan"/> <bean class="com.yuanhuan.service.ZhuGuan" id="zhuGuan"> <property name="worker" ref="liSi"/><!--意思是将liSi对象赋值给zhuGuan对象中的worker属性(worker对象必须要有set方法)--> </bean> </beans>
注:需要张三做测试的时候,只需要在beans.xml中的把liSi换为zhangSan即可。
四. 依赖注入(下面内容都是说String通过beans.xml怎样来注入属性,构造方法等。都是一些具体写法,实际内容不多)
1. 属性注入;
<!--属性注入-->
<bean class="com.yuanhuan.service.People" id="people">
<property name="name" value="张三"/>
<property name="age" value="21"/>
</bean>
2. 构造函数注入;(通过类型;通过索引;联合使用)
<!--构造方法注入(通过类型)-->
<bean class="com.yuanhuan.service.People" id="people2">
<constructor-arg type="java.lang.String" value="李四"/>
<constructor-arg type="int" value="22"/>
</bean>
<!--构造方法注入(通过索引)-->
<bean class="com.yuanhuan.service.People" id="people3">
<constructor-arg index="0" value="王五"/>
<constructor-arg index="1" value="25"/>
</bean>
<!--构造方法注入(默认按顺序)也可使用联合注入(结合类型和索引)-->
<bean class="com.yuanhuan.service.People" id="people4">
<constructor-arg value="王六"/>
<constructor-arg value="26"/>
</bean>
3. 工厂方法注入;(非静态工厂,静态工厂)
<!--非静态工厂方法注入(通过方法制造对象)-->
<bean id="peopleFactory" class="com.yuanhuan.service.PeopleFactory"/>
<bean id="people6" factory-bean="peopleFactory" factory-method="createPeople"/>
<!--静态工厂方法注入-->
<bean id="people7" class="com.yuanhuan.service.PeopleFactory" factory-method="createStaticPeople"/>
4. 泛型依赖注入;(Spring4 整合 Hibernate4 的时候顺带讲)
5. 参数注入
- 基本类型值;
- 注入 bean;
- 内部 bean;
- null 值;
- 级联属性;
- 集合类型属性;
beans.xml <beans><beans>中代码如下:
<!--基本类型值注入-->
<bean class="com.yuanhuan.service.People" id="people">
<property name="name" value="张三"/>
<property name="age" value="21"/>
</bean>
<!--注入bean-->
<bean id="dog1" class="com.yuanhuan.service.Dog">
<property name="name" value="Jack"/>
</bean>
<bean id="people8" class="com.yuanhuan.service.People">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="dog" ref="dog1"/>
</bean>
<!--内部注入bean-->
<bean id="people9" class="com.yuanhuan.service.People">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="dog">
<bean class="com.yuanhuan.service.Dog">
<property name="name" value="jac内部"/>
</bean>
</property>
</bean>
<!--注入null-->
<bean id="people10" class="com.yuanhuan.service.People">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="dog">
<null></null>
</property>
</bean>
<!--注入级联属性-->
<bean id="people11" class="com.yuanhuan.service.People">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="dog.name" value="jack级联"/><!--注意:使用级联属性注入时,原People中dog属性必须初始化,否则会报空指针-->
</bean>
<!--注入集合-->
<bean id="people12" class="com.yuanhuan.service.People">
<property name="name" value="张三"/>
<property name="age" value="15"/>
<property name="dog" ref="dog1"/><!--dog1是注入bean(上面定义过的)-->
<!--(List)-->
<property name="hobbies">
<list>
<value>吃烧烤</value>
<value>喝啤酒</value>
</list>
</property>
<!--(Set)-->
<property name="love">
<set>
<value>唱歌</value>
<value>跳舞</value>
</set>
</property>
<!--(Map)-->
<property name="score">
<map>
<entry>
<key><value>语文</value></key>
<value>90</value>
</entry>
<entry>
<key><value>数学</value></key>
<value>100</value>
</entry>
</map>
</property>
</bean>
测试代码
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
People people = (People) ac.getBean("beans.xml中对应id值");
System.out.println(people);
People代码:
package com.yuanhuan.service;
import java.util.*;
public class People {
String name;
int age;
Dog dog=new Dog();
public People() {
super();
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
List<String> hobbies = new ArrayList<>();
Set<String> Love = new TreeSet<>();
Map<String, Integer> score = new HashMap<>();
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public Set<String> getLove() {
return Love;
}
public void setLove(Set<String> love) {
Love = love;
}
public Map<String, Integer> getScore() {
return score;
}
public void setScore(Map<String, Integer> score) {
this.score = score;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
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;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", dog=" + dog.getName() +
", hobbies=" + hobbies +
", Love=" + Love +
", score=" + score +
'}';
}
}
6.Spring 自动装配(自动装配机制慎用,它屏蔽了装配细节,容易产生潜在的错误)
通过配置 default-autowire 属性,Spring IOC 容器可以自动为程序注入 bean;默认是 no,不启用自动装配; default-autowire 的类型有 byName(根据bean名称),byType(根据bean类型),constructor(根据构造方法名称)
-
需要在beans.xml中加入default-autowirr属性
<?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.xsd" **default-autowire="default"**>
-
具体实例
-
当default-autowire=“byName”:
<!--根据名称自动注入bean--> <bean id="dog" class="com.yuanhuan.service.Dog"> <property name="name" value="Jack"/> </bean> <bean id="people13" class="com.yuanhuan.service.People"> <property name="name" value="王麻子"/> <property name="age" value="55"/> <!–自动注入dog–> </bean>
-
当default-autowire=“byType”:
<!--根据类型自动注入--> <bean id="dog" class="com.yuanhuan.service.Dog"> <property name="name" value="Jack"/> </bean> <bean id="people14" class="com.yuanhuan.service.People"> <property name="name" value="王麻子"/> <property name="age" value="55"/> <!–自动注入dog1(尽管People中没有dog1而是dog,但根据属性自动注入也能注入)–> </bean>
-
当default-autowire=“constructor”:
<!--根据构造方法注入(People类中必须有参数为Dog的构造方法)--> <bean id="dog" class="com.yuanhuan.service.Dog"> <property name="name" value="Jack"/> </bean> <bean id="people14" class="com.yuanhuan.service.People"> <property name="name" value="王麻子"/> <property name="age" value="55"/> <!--根据构造方法自动注入bean(dog)--> </bean>
-
7. 方法注入(用的比较少,了解)
Springbean 作用域默认是 单例 singleton(每个bean生成一个对象)意思就是通过bean注入,每次对象都为同一个对象;
配置步骤(以人类有属性狗类为例子):
- 将人类改为抽象类
- 将getDog改为抽象方法
- 在Dog bean中加一个scope=“prototype”
- 在People bean 中把dog property改为<lookup-method name=“getDog” bean=“dog”/>
8. 方法替换(用的比较少,了解)
利用bean可以实现一个对象执行另一个对象中的方法
五. bean直接的关系
-
继承;
-
依赖;
-
引用
对应实例:
<!--继承-->
<bean id="abstractPeople" class="com.yuanhuan.service.People2" abstract="true">
<property name="className" value="大三"/>
</bean>
<bean id="xiaoming" parent="abstractPeople">
<property name="name" value="小明"/>
<property name="age" value="15"/>
</bean>
<bean id="xiaofang" parent="abstractPeople">
<property name="name" value="小芳"/>
<property name="age" value="12"/>
</bean>
<!--依赖(假如小华依赖小芳),-->
<bean id="xiaofang" parent="abstractPeople" depends-on="xiaofang"><!--当创建小华bean时,会先去创建小芳bean-->
<property name="name" value="小芳"/>
<property name="age" value="12"/>
</bean>
<!--引用(就是前面提到的<property name="dog1" ref="dog">,就是将dog bean 对象注入dog1中)-->
六. bean的作用范围
- singletonSpring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;
- prototype 每次从容器中调用 Bean 时,都返回一个新的实例;
- request 每次 HTTP 请求都会创建一个新的 Bean;
- session 同一个 HTTPSession 共享一个 Bean;
- globalsession 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
- application 同一个 Application 共享一个 Bean;
七. Spring AOP(面向切面编程,说的通俗易懂就是可以动态的,不修改源代码的情况下为程序添加功能,如在一个方法的前后添加一下功能)
AOP实例分类
- 前置通知;
- 后置通知;
- 环绕通知; (环绕通知相当于前后置通知的结合)
- 返回通知;
- 异常通知
例子(在 beans.xml中)
注意:在定义切点时 * 表示匹配任意方法或类或包,(…)表示方法参数为空或任意类型任意多少。
切面:表示动态添加功能的类
切点:表示在哪个类的哪个方法添加切面
首先在beans.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
具体例子:
<bean id="studentManager" class="com.yuanhuan.service.StudentManagerImp"/>
<bean id="studentAspect" class="com.yuanhuan.AOP.StudentAspect"/>
<aop:config><!--切面配置-->
<aop:aspect id="studentAspect" ref="studentAspect"><!--定义一个切面-->
<aop:pointcut id="studentPoinCut" expression="execution(* com.yuanhuan.service.StudentManagerImp.add(..))"/><!--定义一个切点-->
<!-前置通知-->
<aop:before method="addStudentBefore" pointcut-ref="studentPoinCut"/><!--在切点前执行方法addStudentBefore-->
<!-后置通知-->
<aop:after method="addStudentAfter" pointcut-ref="studentPoinCut"/>
<!-环绕通知-->
<aop:around method="doAround" pointcut-ref="studentPoinCut"/>
<!-异常通知-->
<aop:after-throwing method="doAfterThrowing" pointcut-ref="studentPoinCut" throwing="throwable"/>
</aop:aspect>
</aop:config>
//StudentAspect.java(切面类)
public class StudentAspect {
//前置通知
public void addStudentBefore(JoinPoint jp) {
//JoinPoint中封装了很多方法,下面三个依次为获取类、方法名、参数(参数时一个数组,下面[0]就是表示第一个参数)
System.out.println(jp.getTarget().getClass());
System.out.println(jp.getSignature().getName());
System.out.println(jp.getArgs()[0]);
System.out.println("准备添加学生");
}
//后置通知
public void addStudentAfter(JoinPoint jp){
System.out.println("添加学生完成");
}
//环绕通知
public void doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("准备添加学生【环绕通知】");
pjp.proceed();//将切点方法转换到这里执行,这个会返回一个值,就为原切点方法返回的值
System.out.println("添加学生完成【环绕通知】");
}
//异常通知
public void doAfterThrowing(JoinPoint jp,Throwable throwable) {
System.out.println(throwable.getMessage());
System.out.println("异常通知");
}
}
八. 对jdbc的支持(方便数据库的操作)
1.配置:引入包
Spring包:
jdbc包:
dbcp包:
2.修改beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--数据源(class为apache的数据库连接池)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--加载指定路径的配置文件-->
<context:property-placeholder location="jdbc.properties"/>
<!--定义jdbcTemplate bean,注入数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--将jdbcTemplate注入需要使用的类中-->
<bean id="studentDao" class="com.yuanhuan.dao.impl.StudentDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="studentService" class="com.yuanhuan.service.impl.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
</beans>
3.具体使用
public class StudentDaoImpl implements StudentDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public int addStudent(Student student) {
//只需要写核心业务,其他异常,连接什么的都封装好了
String sql = "insert into User values(null,?,?)";
Object[] params = new Object[]{student.getName(), student.getAge()};
return jdbcTemplate.update(sql,params);
}
@Override
public int updateStudent(Student student) {
String sql = "update User set name=?,age=? where id=?";
Object[] params = new Object[]{student.getName(), student.getAge(), student.getId()};
return jdbcTemplate.update(sql,params);
}
@Override
public int deleteStudent(Student student) {
String sql = "delete from User where id=?";
Object[] params = new Object[]{student.getId()};
return jdbcTemplate.update(sql,params);
}
@Override
public List<Student> findStudents() {
String sql="select * from User";
List<Student> students = new ArrayList<>();
jdbcTemplate.query(sql, new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
students.add(new Student(rs.getInt("id"), rs.getString("name"), rs.getInt("age")));
}
});
return students;
}
}
4.jdbcSupport(可以简化一点jdbcTemplate的配置)
在需要使用jdbcTemplate的类中继承JdbcDaoSupport ,beans.xml中就不用配置jdbcTemplate,只需要向需要使用jdbcTemplate的类的bean中直接注入数据源(property name=dataSource),使用时直接this.getJdbcTemplate()就可以了。
5.NamedParameterJdbcTemplate(支持命名参数,就是在写sql语句时,参数更加直观)
九. 对事务的支持
例如银行转账,A转账给B,若A转账后出现异常,此时B未收到钱,此时需要恢复A转账之前的状态。这个就时事务的原子性(一个事务要么不执行,要么全部执行)
1. 事务简介(需满足下面条件之一)
- 原子性;
- 一致性;
- 隔离性;
- 持久性
2. 编程式事务管理(缺点:代码入侵事务本身代码,导致代码乱)
- 需要使用事务管理器(transactionTemplate)类中:
public class TransactionService {
private TransactionTemplate transactionTemplate;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
public void doTransactionTest(){
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
//在这个方法中执行的语句就是一个事务
System.out.println("执行一个事务");
}
});
}
}
- beans.xml中
<!--数据源(class为apache的数据库连接池)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--添加transactionTemplate bean-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!--在需要使用transactionTemplate中注入transactionTemplate bean-->
<bean id="transactionService" class="com.yuanhuan.service.TransactionService">
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
- test:
public class TransactionTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService");
transactionService.doTransactionTest();
}
}
3.声明式事务管理: (通过事务切面)
1. 使用xml 配置声明式事务:在beans.xml中几行搞定,比较常用。
- 修改beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
- 添加事务通知
<!--数据源(class为apache的数据库连接池)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--对所有方法 -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--配置事务切面-->
<aop:config>
<!--配置切点-->
<aop:pointcut id="serviceMethod" expression="execution(* com.yuanhuan.service.*.*(..))"/>
<!--配置事务通知,对切点进行事务管理,也就是切点都为一个事务-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
2. 使用注解配置声明式事务,就是在方法上面加@XXX,虽简单,但是对于大项目,积少成多。)
- 在beans.xml中
<!--数据源(class为apache的数据库连接池)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
- 在需要进行事务管理的类或方法前面加: @Transactional
4.事务传播(某个service类需要调用另一个service类,且因为每个service方法都有事务,这是后就有事务的嵌套,从而产生了事务的传播行为)
- 种类(在<tx:method name="*"/>中添加propagation=? 来配置,?号值为下面六种,一般只用第一种):
- REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
- SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
- REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
- NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
十.自动添加bean
在beans.xml中可以配置一下,然后在每个类前加@XXX,Spring就会自动为其添加bean(类中属性类也可以添加@XXX(xxx需要与本身类相同),自动注入bean)