多种方式实现依赖注入及使用注解定义bean
构造注入
如何给构造方法中的参数注入方法呢如下
首先bean代码如下
package cn.pojo; public class Greeting { /** * 说的话 */ private String words; /** * 说话的人 */ private String person;
private Greeting greeting; public void sayGreeting() { System.out.println(person+"说:"+words); } public Greeting getGreeting() { return greeting; } public void setGreeting(Greeting greeting) { this.greeting = greeting; } public Greeting() { // TODO Auto-generated constructor stub } public Greeting(String words1,String person1) { this.words=words1; this.person=person1; } public String getWords() { return words; } public void setWords(String words) { this.words = words; } public String getPerson() { return person; } public void setPerson(String person) { this.person = person; } }
xml注入代码如下
<!-- id为实例后对象名 class为对象的类型 --> <bean id="greeting1" class="cn.pojo.Greeting"> <!--name为构造参数中的参数名称 value为值 --> <constructor-arg value="三天不打鬼子,手都不自在" name="words1"/> <constructor-arg value="小兵张嘎" name="person1"/> </bean>
这段个代码跟下面这段Java代码的意思是一样的,实例化一个名叫 greeting1的对象并且传入两个参数 ,name则对应参数的名称
Greeting greeting1 = new Greeting("三天不打鬼子,手都不自在","小兵张嘎");
测试代码如下
//找到配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Greeting greeting1 = (Greeting)context.getBean("greeting1"); greeting1.sayGreeting();
结果如下
注入属性
注入代码如下
<bean id="greeting1" class="cn.pojo.Greeting"> <!--name为构造参数中的参数名称 value为值 --> <constructor-arg value="三天不打鬼子,手都不自在" name="words1"/> <constructor-arg value="小兵张嘎" name="person1"/> <!-- 此段代码相当于 实例化Greeting类后调用set方法对属性名为greeting的属性进行赋值,只不过赋值的类型是自定义的类类型--> <property name="greeting" ref="greeting2"/> </bean> <bean id="greeting2" class="cn.pojo.Greeting"> <!--name为构造参数中的参数名称 value为值 给Greeting中的words和person赋值,相当于调用set方法进行赋值--> <property name="words" value="世界上有十种人,认识二进制和不认识二进制的"/> <property name="person" value="Rod"/> </bean>
再编写bean时需要注意些setget方法,否则注入时将会出现异常
测试类代码
//找到配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Greeting greeting1 = (Greeting)context.getBean("greeting1"); greeting1.getGreeting().sayGreeting(); greeting1.sayGreeting();
运行结果
p命名空间注入
首先使用p需要导入 xmlns:p="http://www.springframework.org/schema/p" 才能使用 这个地址访问会出404不用管 是正常的可以用。注意区分大小写
<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.2.xsd ">
p命名空间简化了属性的注入,简化了配置的方法,大大的简化了配置的工作量 如下
<!-- 对类类型的属性进行赋值分号后为 属性名加-ref 即 greeting-ref--> <bean id="greeting1" class="cn.pojo.Greeting" p:greeting-ref="greeting2"> <!--name为构造参数中的参数名称 value为值 --> <constructor-arg value="三天不打鬼子,手都不自在" name="words1"/> <constructor-arg value="小兵张嘎" name="person1"/> </bean> <!-- 分号后面为 属性名称 --> <bean id="greeting2" class="cn.pojo.Greeting" p:words="世界上有十种人,认识二进制和不认识二进制的" p:person="Rod"/>
使用注解定义bean
注意:如果是jdk1.8的最好不要用spring3,或者使用jdk1.7。否则很可能会出现不兼容,之前我就亲身经历了这个问题。于是我就换成了spring 4
jar下载网址:http://repo.spring.io/release/org/springframework/spring/
使用注解定义bean又进一步的减少了配置文件的代码量
首先定义一个接口然后仔定义实现类
//通过注解定义了一个dao,此注解相当于 实例化了一个名叫 userDao UserDaoImppl类型的对象,是跟在xml中定义了一个bean一样的效果 @Component("userDao") public class UserDaoImpl implements UserDao { @Override public void save(User u) { System.out.println("保存用户信息到数据库!"); } }
编写业务层
//此注解相当于实例化了名为 userService的对象,也是跟xml定义了一个bean一样的效果 @Service("userService") public class UserServiceImpl implements UserService{ //查找名为userDao的bean,并注入给dao属性 @Resource(name="userDao") private UserDao dao; public UserDao getDao() { return dao; } public void setDao(UserDao userDao) { this.dao = userDao; } @Override public void save(User u) { // TODO Auto-generated method stub dao.save(u); } }
或者这样也是可以的
//此注解相当于实例化了名为 userService的对象 @Service("userService") public class UserServiceImpl implements UserService{ //查找名为dao的bean,并注入给dao属性 @Autowired @Qualifier("userDao") private UserDao dao; public UserDao getDao() { return dao; } public void setDao(UserDao userDao) { this.dao = userDao; } }
或者这样
@Autowired private UserDao dao;
亦或者这样
@Resource private UserDao dao;
上述的几种方式结果都是一样的 @Resource和@Autowired默认会寻找符合条件的bean 而 @Component("userDao")正好满足。而他们的赋值是跟setget没有关系的即使去掉也
没得事
userConfig代码如下
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd "> <!-- 扫描指定目录下的所有文件 可以直接写 所有包的“父亲”cn也可以 --> <context:component-scan base-package="cn.dao.impl,cn.service.impl"/> </beans>
测试类代码如下
ApplicationContext context = new ClassPathXmlApplicationContext("userConfig.xml"); UserService userDao = (UserServiceImpl)context.getBean("userService"); User u = new User(); userDao.save(u);
结果如下
- @Component 是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。
- @Repository:用于标注Dao类
- @Service:用于标注业务类
- @Controller:用于标注控制权类
它们的作用都是定义一个bean,看到不同的注解的时候可以方便区分此bean时干嘛用的。