前面我们都是xml配置文件的形式实现bean的装配,接下来我们介绍一下用注解实现bean的装配.和前面的Mybatis一样,使用注解会很方便.
首先我们介绍一下几个注解:
@Component :用于创建对象 就等价于 <bean class=""></bean> 注意:前面我们使用xml配置文件要获得对象,如果bean里面没有id值是不能获取的.但是这里@Component和<bean class=""></bean>等价却是可以创建对象的,因为它其实是将没有定义的id默认为类的名字
@Component("id") :用于创建对象 <=> <bean id = "" class=""></bean>
下面这三个的作用和上面的@Component的作用一模一样 都是创建对象;区分出来的目的就是为了分层的
@Controller : 表示层
@Service :业务逻辑层
@Repository :数据持久层
在固定的层使用固定的注解来创建对象就可以了.其实是可以混用的
------------------------上面注解用于创建对象,下面的用于注入值--------------------------
这里就出现一个问题,如果用注解来代替<bean>创建对象,那如何向对象里面注入数据呢?参数如何赋值呢?
这里我们就用下面的注解
按照类型自动注入---@Autowired:
以UserServiceImpl这个实现类为例,它需要一个UserDao的实现类对象传入,这时候其实就可以在private上面@Autowired,构造和setter方法都可以不要这里其实是spring框架会自动帮我们在整个容器中取寻找这个类型 ,找到所对应的类型.
如果找不到:不注入
找到一个:注入成功
找到多个:抛出异常
因为一个类会有很多对象,如过找到多个会报出异常,那如何解决呢?就用下面的按照名称注入
按照名称注入:
每一个对象都有一个id,例如我们上面说用Component("id")来创建对象起得id名,因为这个id是唯一标识,我们用这个来区分就可以了.分为下面两种方式:
一,组合使用:@Autowired
@Qualifier("name")
二:@Resource(name = "")
上面的name都是需要传入的对象的id值
注意:使用注解有一个前提:必须在原理导入jar包(4+1)的基础上再多导入一个spring-aop.jar包才能实现
下面我们就不使用xml文件了,来使用注解来创建一下对象:
首先我们还是新建一个java项目,并将我们的jar包导入(Spring核心4+1外加spring-aop.jar).然后在src下创建一个dao包,里面有一个UserDao这个接口
package dao;
public interface UserDao {
void addUser();
void deleteUser();
}
dao包下有一个子包impl,里面是UserDao的实现类UserDaoImpl
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
我们需要创建一个applicationContext.xml配置文件,按照以前,通过<bean>标签来创建对象
<?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">
<!--<bean>......</bean>,这是以前的-->
</baens>
现在我们要使用注解来创建对象来代替xml中的<bean>,所以上面的配置文件我们就不写<bean>标签了.那么我们就可以在UserDaoImpl的类声明上方加上@..注解即可.当然我们可以使用@Component;但是dao是数据持久层交互的,我们用@Repository("userdao")并起个名字方便获取更好一点.添加好注释的UserDaoImpl类如下面:这样我们就相当于创建了数据持久层UserDaoImpl的对象,并赋予了一个id
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
@Repository("userdao")
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
是不是就可以了呢?我们写个测试来测试一下
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.UserDao;
import dao.impl.UserDaoImpl;
public class Test {
public static void main(String[] args) {
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = ac.getBean("userdao", UserDaoImpl.class);
dao.addUser();
}
}
结果是报出异常:说没有userdao被定义..这是为什么呢?
注意:这里我们获得容器对象是从通过ClassPathXmlApplicationContext这个类来取得上下文,然后通过上下文得到对象的.但是现在xml配置文件中什么都没有,也就是说对于上线文或者对于spring容器来说,并不知道UserDaoImpl的存在.其实这里我们缺少的东西是要告诉上下文我们的对象是注解处被创建,将它管理起来.方便我们以后获取.那我们如何让上下文来知道们我要创建的对象在哪来存在呢?这时候就要讲我们的配置文件啦
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--在这个上下文中,我们需要告诉它去哪里找我们用注解创建的对象,种类需要用到命名空间
上面xmlns="http://www.springframework.org/schema/beans"这个就是命名空间
是一个默认的命名空间,我们这里需要一个context的命名空间,那就抄一个.由于默认的就一个,这里我们给它一个别名context;
由于默认的是beans的,所以这里最后我们要把beans改为context
-->
<!--
命名空间是做什么的呢?
在schema中:通过name space 也就是命名空间来规范标签的;在每一个命名空间底下都声明了很多特定的标签
我们以前之所以能用bean这个标签是因为它在默认的命名空间底下,所谓的beans对应的路径下声明着
我们现在要做的是让spring ioc容器知道UserDaoImpl这个对象的存在,所以它需要用到是上下文的命名空间,所以我们在上面
用xmlns:context="http://www.springframework.org/schema/context"声明出来这个命名空间
也就是说,把这些所有内容都包含到上下文中去
但是仅仅像上面那样声明是没有标签的,只是说要引用context,但是里面有哪些标签,去哪里找还要通过xsi:schemaLocation来决定
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
将这两句添加到上面的xsi:schemaLocation中,这样我们就知道了context命名空间里面都有哪些标签以及所代表的含义
之所以我们这样修改,是因为spring的命名空间和约束名字起得都特别规范,这样我们就可以方便添加.
-->
<!--
这里我们要用context:component-scan这个标签
base-package:通过包的名字来进行扫描的,我们这里要创建UserDaoImpl这个对象它在dao.impl这个包下,这里我们就写dao就可以了
会将dao和它子包impl包下的所有类都扫描
这是我们就可以创建了
-->
<context:component-scan base-package="dao" ></context:component-scan>
</beans>
一些重要的内容,我都随着注释写在配置文件中啦.这时候我们再来测试一下:
就成功了.这个就是简单的用注解实现bean的装配