- Spring依赖注入(DI)
- Setter方法注入
接口、实现类和Helper类:
// 接口 public interface People { public void talk(); }
// 实现类 public class American implements People { public void talk() { System.out.println("Hello,I'm an American"); } }
// Helper类 public class TalkHelper { People people; public TalkHelper(People people) { this.people = people; } public void setPeople(People people) { this.people = people; } public void talk() { people.talk(); } }
Spring 配置:
Test:<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="OutputHelper" class="com.winne.talk.TalkHelper"> <property name="people" ref="American" /> </bean> <bean id="American" class="com.winne.talk.impl.American" /> </beans>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yiibai.output.OutputHelper; public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); TalkHelper talkHelper = (TalkHelper)context.getBean("TalkHelper"); talkHelper.talk(); } }
结果:
Hello,I'm an American - 构造器注入 Spring配置:
<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="TalkHelper" class="com.winne.talk.TalkHelper"> <constructor-arg> <ref bean="American" /> </constructor-arg> </bean> <bean id="American" class="com.winne.talk.American" /> </beans>
注:有多参数多构造方法的类使用构造器注入可能会导致类型歧义,解决方案见我的另一篇文章。
- Spring Bean
- Spring EL
两个简单的bean:
public class People {
private House house;
private String houseAddr;
}
public class House {
private String addr;
private int yearLimit;
}
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 id="houseBean" class="com.winne.core.House">
<property name="addr" value="Hangzhou" />
<property name="yearLimit" value="50" />
</bean>
<bean id="peopleBean" class="com.winne.core.People">
<property name="house" value="#{houseBean}" />
<property name="houseAddr" value="#{houseBean.addr}" />
</bean>
</beans>
结果:
winne的house即houseBean,houseAddr为Hangzhou,houseBean的addr为Hangzhou,yearLimit为50.(我这么说,聪明的你一定看的懂)
注解形式:
@Component("peopleBean")
public class People {
@Value("#{houseBean}")
private House house;
@Value("#{houseBean.addr}")
private String houseAddr;
// do something
}
@Component("houseBean")
public class House {
@Value("Hangzhou") // 直接注入字符串
private String addr;
@Value("50") // 直接注入整型
private int yearLimit;
// do something
}
<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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.winne.core" />
</beans>
注:如果bean是在XML里注册的,但@Value是定义在Java类里的,那么该@Value就不会执行咯~~
还可以调用方法@Value("#{houseBean.toString()}"),支持大多数标准的数学,逻辑和关系运算符(==,!=,<,>,<=,>=,and,or,!,+,-,*,/,%,^),以及三元操作符(...?A:B),取list(@Value("#{testBean.xxxList[0]}"))或map(@Value("#{testBean.xxxMap['key1']}")),还可以支持正则表达式@Value("#{'100' matches '\\d+'}")
- Spring自动组件扫描
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-2.5.xsd">
<bean id="userService" class="com.winne.user.service.UserService">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="userDAO" class="com.winne.user.dao.UserDAO" />
</beans>
自动组件扫描:
import org.springframework.stereotype.Component;
@Component
public class UserDAO
{
@Override
public String toString() {
return "Hello , This is UserDAO";
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.winne.user.dao.UserDAO;
@Component
public class UserService
{
@Autowired
UserDAO userDAO;
@Override
public String toString() {
return "UserService [userDAO=" + userDAO + "]";
}
}
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 在 Spring 中启用自动扫描功能 base-package指明存储组件,Spring将扫描这个文件夹,找出注解了@Component的bean并注册到spring容器 -->
<context:component-scan base-package="com.winne.user" />
</beans>
在Spring2.5中,有4种类型的组件自动扫描注释类型 @Component – 指示自动扫描组件。 @Repository – 表示在持久层DAO组件。 @Service – 表示在业务层服务组件。 @Controller – 表示在表示层控制器组件。
其实,你都注册成@Component,也是没问题的。但为了便于阅读,还是该声明成哪个就声明成哪个吧。
另,如果你想修改组件的名字,可以这样做,例@Service("XXX")。