前面章节:
第二节:spring ioc
http://blog.csdn.net/javastudyr/article/details/17057699
开始学习注解
<?
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 这里必须写这个才能注入成功 -->
<
context:annotation-config />
<
bean
name
=
"userDAO"
class
=
"com.test.dao.impl.UserDAOImpl"
>
<
property
name
=
"daoId"
value
=
"1"
></
property
>
</
bean
>
<
bean
id
=
"userService"
class
=
"com.test.service.UserService"
>
<!-- <property name="userDAO" bean="u" />修改为下面的样子 -->
<!-- <property name= "userDAO" ref = "userDAO" /> -->
</
bean
>
</
beans
>
2.
<
context:annotation-config
/>的作用
它的作用是初始化了
AutowiredAnnotationBeanPostProcessor
,
CommonAnnotationBeanPostProcessor
,
PersistenceAnnotationBeanPostProcessor
, as well as the aforementioned
RequiredAnnotationBeanPostProcessor
记住这些就是用来处理我们注解的bean
3.autowired(通过byType来注入的) 注入
public
class
UserService {
private
UserDAO
userDAO
;
public
UserDAO getUserDAO() {
return
userDAO
;
}
@Autowired
public
void
setUserDAO(UserDAO userDAO) {
this
.
userDAO
= userDAO;
}
public
void
addUser(User user ){
userDAO
.save(user);
};
}
最好写在setter 上面,如果写在
private
UserDAO
userDAO
;上面,破换封装性
4.
@
Resource
(默认是byName方法来注入)注入
public
class
UserService {
private
UserDAO
userDAO
;
//现在是这样,通过配置文件来实例化
public
UserDAO getUserDAO() {
return
userDAO
;
}
@Resource
public
void
setUserDAO(UserDAO userDAO) {
this
.
userDAO
= userDAO;
}
public
void
addUser(User user ){
userDAO
.save(user);
};
}
推荐使用
@
Resource
5.component(组件)注解
在spring 中如果不想自己写bean,也可以用组件来让spring 为你写
代码:
在userDAOImpl 上加一个组件注解
@Component
public
class
UserDAOImpl
implements
UserDAO{
private
int
daoId
;
public
int
getDaoId() {
return
daoId
;
}
public
void
setDaoId(
int
daoId) {
this
.
daoId
= daoId;
}
@Override
public
void
save(User u) {
System.
out
.println(
"save user"
+
this
.
daoId
);
}
}
修改beans
<?
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.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<!-- 这里必须写这个才能输入成功 -->
<
context:annotation-config
/>
<
context:component-scan
base-package
=
"com.test"
/>
<
bean
id
=
"userService"
class
=
"com.test.service.UserService"
>
</
bean
>
</
beans
>
这里只有 userService 了,没有dao的bean了
然后我们来运行一下
结果一样
从结果中我们发现,虽然我们没有写dao的bean,但是spring帮我们写了。。。
我们这里说一下spring的写了的过程
首先加载beans.xml ,发现有
<
context:annotation-config
/>
<
context:component-scan
base-package
=
"com.test"
/>
然后spring就会去扫描我们给他定好的包
base-package
=
"com.test"
扫描到UserDAOImpl 的时候,发现有compont组件,就会把这个组件存到容器里面去(键值对的形式)key(名字)userDAOImpl(就是把首字母小写) ,值就是实例对象,然后继续,发现resource这个注入注解,就会按名称把这个注入进来
如果要使用我们的名字
代码:
@Component (value="userDao" )//这里我们名字为userDao
public
class
UserDAOImpl
implements
UserDAO{
private
int
daoId
;
public
int
getDaoId() {
return
daoId
;
}
public
void
setDaoId(
int
daoId) {
this
.
daoId
= daoId;
}
@Override
public
void
save(User u) {
System.
out
.println(
"save user"
+
this
.
daoId
);
}
}
public
class
UserService {
//private UserDAO userDao=new UserDAOImpl();原来是这样的
private
UserDAO
userDAO
;
//现在是这样,通过配置文件来实例化
public
UserDAO getUserDAO() {
return
userDAO
;
}
@Resource(name= "userDao" )//这里注入的时候去通过名字来取实例,所以也要叫userDao
public
void
setUserDAO(UserDAO userDAO) {
this
.
userDAO
= userDAO;
}
public
void
addUser(User user ){
userDAO
.save(user);
};
}
运行结果:
save user0
如果我们的给的名字不一样,会发生什么喃?
@Resource
(name=
"userDAO"
)//我把名字改为大写
我们来看下结果:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService':
我直截取了第一句,意思就是bean工厂创建错误,意思就是没有这个userDao,而去创建了userDAO,所以会报这个错误
我觉得写上名字好些
这里补充一点component的知识
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
在 一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。 Spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了 @Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用 和在xml文件中使用bean节点配置组件时一样的。要使用自动扫描机制,我们需要打开以下配置信息:
Java代码
1. <?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
2. >
3.
4. <context:component-scan base-package=”com.eric.spring”>
5. </beans>
/*其中base-package为需要扫描的包(含所有子包)
@Service用于标注业务层组件,
@Controller用于标注控制层组件(如struts中的action),
@Repository用于标注数据访问组件,即DAO组件,
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
*/
注入方式:
把 DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注入时不要new 这个注入的类,因为spring会自动注入,如果手动再new的话会出现错误,然后属性加上@Autowired后不需要getter()和 setter()方法,Spring也会自动注入。至于更具体的内容,等对注入的方式更加熟练后会做个完整的例子上来。
注解:
在 spring的配置文件里面只需要加上<context:annotation-config/> 和<context:component-scan base-package="需要实现注入的类所在包"/>,可以使用base-package="*"表示全部的类。
<context:component-scan base-package=”com.eric.spring”>
其中base-package为需要扫描的包(含所有子包)
在接口前面标上@Autowired和@Qualifier注释使得接口可以被容器注入,当接口存在两个实现类的时候必须指定其中一个来注入,使用实现类首字母小写的字符串来注入。
@Service服务层组件,用于标注业务层组件,表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,如果需要自己改名字则:@Service("你自己改的bean名")。
@Controller用于标注控制层组件(如struts中的action)
@Repository持久层组件,用于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
6.那controller有什么作用喃?它有不需要new,注解它到底为了什么喃?
在 一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。 Spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了 @Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用 和在xml文件中使用bean节点配置组件时一样的。要使用自动扫描机制,我们需要打开以下配置信息:
Java代码
1. <?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
2. >
3.
4. <context:component-scan base-package=”com.eric.spring”>
5. </beans>
/*其中base-package为需要扫描的包(含所有子包)
@Service用于标注业务层组件,
@Controller用于标注控制层组件(如struts中的action),
@Repository用于标注数据访问组件,即DAO组件,
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
*/
注入方式:
把 DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注入时不要new 这个注入的类,因为spring会自动注入,如果手动再new的话会出现错误,然后属性加上@Autowired后不需要getter()和 setter()方法,Spring也会自动注入。至于更具体的内容,等对注入的方式更加熟练后会做个完整的例子上来。
注解:
在 spring的配置文件里面只需要加上<context:annotation-config/> 和<context:component-scan base-package="需要实现注入的类所在包"/>,可以使用base-package="*"表示全部的类。
<context:component-scan base-package=”com.eric.spring”>
其中base-package为需要扫描的包(含所有子包)
在接口前面标上@Autowired和@Qualifier注释使得接口可以被容器注入,当接口存在两个实现类的时候必须指定其中一个来注入,使用实现类首字母小写的字符串来注入。
@Service服务层组件,用于标注业务层组件,表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,如果需要自己改名字则:@Service("你自己改的bean名")。
@Controller用于标注控制层组件(如struts中的action)
@Repository持久层组件,用于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
6.那controller有什么作用喃?它有不需要new,注解它到底为了什么喃?
在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。
在struts中
Controller:控制器的作用是从客户端接受请求,并且选择执行相应的业务逻辑,然后把响应结果送回到客户端。在Struts中Controller功能由ActionServlet和ActionMapping对象构成:核心是一个Servlet类型的对象ActionServlet,它用来接受客户端的请求。ActionServlet包括一组基于配置的ActionMapping对象,每个ActionMapping对象实现了一个请求到一个具体的Model部分中Action处理器对象之间的映射。