1.Ioc容器:
(1)读取配置信息(xml文件、配置类、注解配置) ClassPathXmlApplicationContext() annoationConfigApplicationContext()
(2)根据bean的查找实体类 ---getBean("")
(3)将实体类的class文件装载到spring容器 ---new 实体类()
(4)使用bean --调用属性或方法或者其他的需求
2.beanFactory接口和applicationContext接口
beanFactory :bean工厂,是ioc的核心,spring底层基础建设,采用延迟加载
applicationContext:应用上下文,是由BeanFactory派生而来,提供了更多面向实际应用的功能。
面向spring使用和开发的,两个实现类
ClassPathXmlApplicationContext()从class文件中加载配置文件
FileSystemApplicationContext()从文件系统加载配置文件
3.依赖注入DI
(1)配置类java @configration @bean (实际开发中比较少用)
(2)xml方式注入(推荐使用 --属性注入更多)
a.构造方法注入
b.属性注入 /set注入
c.接口注入/(spring未实现 )
(3)注解方式(推荐)
a.构造方法注入
//实体类
public class UserServiceImpl implements UserService{
private UserDao userDao;
private String str;
private List<String> list;
private Set<User> set;
private Map<String,User> map;
public boolean login(String userName, String password) {
System.out.println("----------UserServiceImpl----------");
System.out.println(str);
System.out.println(list);
System.out.println(set);
System.out.println(map);
return this.userDao.login(userName, password);
}
public UserServiceImpl(UserDao userDaol,String str,List<String> list,Set<User> set,Map<String,User> map) {
super();
this.userDao = userDaol;
this.str=str;
this.list=list;
this.set=set;
this.map=map;
}
}
//配置文件
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean name="userSeriver" class="com.neuedu.service.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
<constructor-arg name="str" value="张三"></constructor-arg>
<constructor-arg name="list">
<list>
<value>qqqq</value>
<value>www</value>
<value>eeee</value>
</list>
</constructor-arg>
<constructor-arg name="set">
<set>
<ref bean="u1"/>如果是别的类,必须参照其他的类
<ref bean="u2"/>
<ref bean="u3"/>
</set>
</constructor-arg>
<constructor-arg name="map">
<map>
<entry key="zhangsan" value-ref="u1"></entry>
<entry key="wewe" value-ref="u2"></entry>
<entry>
<key><value>xcxcx</value></key>
<ref bean="u1"></ref>
</entry>
</map>
</constructor-arg>
</bean>
<bean name="userDao" class="com.neuedu.dao.UserDaoImpl"></bean>
<bean name="u1" class="com.neuedu.entity.User">
<property name="username" value="战三"></property>
<property name="password" value="122435"></property>
<property name="age" value="12"></property>
</bean>
<bean name="u2" class="com.neuedu.entity.User"></bean>
<bean name="u3" class="com.neuedu.entity.User"></bean>
</beans>
//测试类(和xml文件在同一个包下)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"appConfig.xml"})
public class AllTests {
@Autowired
UserService userSeriver;
@Test
public void tt(){
userSeriver.login("sss", "2324");
}
}
b.属性注入 /set注入
要求:实体类必须有set方法
//实体类
public class UserServiceImpl implements UserService{
private UserDao userDao;
private String str;
private List<String> list;
private Set<User> set;
private Map<String,User> map;
public boolean login(String userName, String password) {
System.out.println("----------UserServiceImpl----------");
System.out.println(str);
System.out.println(list);
System.out.println(set);
System.out.println(map);
return this.userDao.login(userName, password);
}
//setters
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setStr(String str) {
this.str = str;
}
public void setList(List<String> list) {
this.list = list;
}
public void setSet(Set<User> set) {
this.set = set;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
}
//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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean name="uservice" class="com.neuedu.service.UserServiceImpl">
<property name="userDao" ref="uDao"></property>
<property name="str" value='1223'></property>
<property name="list">
<list>
<value>dfdf</value>
<value>dfdf</value>
<value>dfdf</value>
</list>
</property>
<property name="set">
<set>
<ref bean="u1"></ref>
<ref bean="u2"></ref>
</set>
</property>
<property name="map">
<map>
<entry key="11" value-ref="u1"></entry>
<entry key="22" value-ref="u2"></entry>
</map>
</property>
</bean>
<bean name="uDao" class="com.neuedu.dao.UserDaoImpl"></bean>
<bean name="u1" class="com.neuedu.entity.User">
<property name="username" value="ddd"></property>
<property name="age" value="18"></property>
</bean>
<bean name="u2" class="com.neuedu.entity.User">
<property name="username" value="ccc"></property>
<property name="age" value="23"></property>
</bean>
</beans>
c.基于注解注入
//appannotConfig.xml文件
注解扫描器
<!-- 加载扫描器 -->
<context:component-scan base-package="com.neuedu"/>
//实体类
//注册组件
@Component("uservice")
public class UserServiceImpl3 implements UserService{
@Autowired //自动装配按照类型查找 (接口类型)
@Qualifier("dao2")//将装配改成按名字查找
private UserDao userDao;
public boolean login(String userName, String password) {
System.out.println("----------UserServiceImpl----------");
return this.userDao.login(userName, password);
}
}
//dao层
@Component("dao2")
public class UserDaoImpl2 implements UserDao {
public boolean login(String userName, String password){
System.out.println("----------UserDaoImpl222222222222222----------");
System.out.println(userName + " login.......");
return true;
}
}
//测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"appannotConfig.xml"})
public class AllTests3 {
@Autowired
UserService uservice;
@Test
public void tt(){
uservice.login("sss", "2324");
}
}
注解详细信息:
@component定义组件 ----类上
@autowired 自动装配bean---属性(按照接口类型查找)
@qualifier 按照名字查找bean,通常和@autowired(使用场景:接口有多个实现类时,用于指定某一个类的)
Spring还提供了三个功能基本和@Component等效的注解,
分别用于对DAO,Service和Web层的Controller进行注解
①@Repository:用于对DAO实现类进行标注
②@Service:用于对Service类进行标注
③@Controller:用于对Controller实现类进行标注
@resource注解 等效于 @Autowired+@qualifier ---用于修饰属性
/*@Autowired //自动装配按照类型查找 (接口类型)
@Qualifier("userDaoImpl")//将装配改成按名字查找
*/ 等效于
@Resource(name="userDaoImpl")
4, bean作用域 scope的取值
单例 singleton
多实例 prototype
请求request
会话 session
应用 globalsession
xml文件:
<bean name="userSeriver" class="com.neuedu.service.UserServiceImpl1" scope="prototype">
<constructor-arg name="userDaol" ref="userDao"></constructor-arg>
</bean>
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("appConfig.xml");
UserService u1=(UserService)app.getBean("userSeriver");
UserService u2=(UserService)app.getBean("userSeriver");
System.out.println(u1+"ccc"+u2);
System.out.println(u1==u2); //false
}
一般我们对有状态的bean使用prototype作用域,而对无状态的bean使用singleton作用域。
在Spring环境下对于所有的DAO类都可以采用单例模式,因为Spring利用AOP和LocalThread功能,
对非线程安全的变量(或称状态)进行处理,使这些非线程安全的类变成了线程安全的类。
有状态的bean:定义了成员属性的类
无状态的bean:没有定义成员属性的类
---总结:spring是线程安全的:
1.有状态的bean可以用prototype多实例模式
2.无状态的bean采用本地线程LocalThread功能实现的线程安全。