spring是一个分层的javaEE一站轻量级开源框架,spring是处理三层架构中的service层的,那么spring和传统的service层有什么区别呢?
我们来看一下在使用spring之前的一段代码。
public class UserServiceImpl implement UserService{
UserDao userDao=new UserDaoImpl();//控制反转
public void addUser(){
userDao.addUser();
}
}
相信这一段代码大家都很熟悉,这就是传统的service层写法,我们在写的时候都会先写一个service接口然后写一个实现类去实现这个接口,这样写的优点是什么?你可能会说是为了有更好的扩展性,方便解耦。那么问题来了,这样写真的有解耦吗?
public class UserServiceImpl implement UserService{
UserDao userDao=new UserDaoImpl();//直接在service层实例化dao,service和dao耦合
public void addUser(){
userDao.addUser();
}
}
我们可以使用依赖注入思想实现service和dao解耦
public class UserServiceImpl implement UserService{
UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void addUser(){
userDao.addUser();
}
}
这样就实现了service和dao的解耦
在我们之前使用service时都是这样的:
UserService service=new UserServiceImp();
在使用spring之后完全就不要使用new来实例化service
Spring的核心思想:控制反转和依赖注入
上面的代码就是控制反转和依赖注入的具体表现,下面我们来看看spring是如何实现一面这一过程的
1.导包
2.创建service
public class UserServiceImpl implements UserService {
private UserDao userDao ;
public void setUserDao(UserDao userDao) {
this. userDao = userDao;
}
@Override
public void addUser(User user) {
// TODO Auto-generated method stub
this. userDao.addUser( user);
}
}
3.创建dao
public class UserDaoImpl implements UserDao{
@Override
public void addUser(User user ) {
// TODO Auto-generated method stub
System. out.println("添加用户" );
}
}
4.创建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">
<!-- 创建 dao实现类 -->
<bean id="userDaoId" class="com.wency.dao.UserDaoImpl" ></bean>
<!-- 创建service -->
<bean id="userService" class="com.wency.a_ioc.UserServiceImpl" >
<property name= "userDao" ref="userDaoId" ></property>
</bean >
</beans>
5.测试类
public class TestUserService {
@Test
public void testAddUser(){
//beans.xml的路径
String configPath="com/wency/a_ioc/Beans.xml" ;
//方法一:使用BeanFactory实现延迟加载beans.xml,userService在第一次调用getBean时才实例化
BeanFactory factory= new XmlBeanFactory(new ClassPathResource(configPath ));
//方法二:使用ApplicationContext加载beans.xml
// ApplicationContext applicationContext=new ClassPathXmlApplicationContext(configPath);
// UserService userService = (UserService) applicationContext.getBean("userService");
UserService service=(UserService) factory.getBean("userService" );
User user= new User();
user. setName("张三");
service.addUser( user);
}
}
在bean.xml中其实是实现了以下的几个步骤
// <
bean
id
=
"userService"
class
=
"com.wency.a_ioc.UserServiceImpl"
>
UserService userService=new UserServiceImpl();
//
<
bean
id
=
"userDaoId"
class
=
"com.wency.dao.UserDaoImpl"
></
bean
>
UserDao userDaoId=new UserDaoImpl();
/**
<
property
name
=
"userDao"
ref
=
"userDaoId"
></
property
>
name的值要和userService中的userDao属性名相同,ref即引用的对象的id
**/
userService.setUserDao(userDaoId);
spring的核心api
BeanFactory
:这是一个工厂,用于生成任意
bean
。
采取延迟加载,第一次
getBean
时才会初始化
Bean
ApplicationContext
:是
BeanFactory
的子接口,功能更强大。(国际化处理、事件传递、
Bean
自动装配、各种不同应用层的
Context
实现)。当配置文件被加载,就进行对象实例化。
ClassPathXmlApplicationContext
用于加载
classpath
(类路径、
src
)下的
xml
加载
xml
运行时位置
--> /WEB-INF/classes/...xml
FileSystemXmlApplicationContext
用于加载指定盘符下的
xml
加载
xml
运行时位置
--> /WEB-INF/...xml
通过
java web ServletContext.getRealPath()
获得具体盘符