Spring IoC(2) --- 注解方式

来源:互联网 发布:洪金宝 黑社会 知乎 编辑:程序博客网 时间:2024/05/17 02:14
spring实现注入一般包括两种方式:xml注解。这里总结下注解的方式。

1.两种获取Bean的区别:
     xml----通过配置获取Bean
     注解----通过java反射,根据bean类型等获取Bean

2.常见注解:
注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired、Resource、Qualifier、Service、Controller、Repository、Component。
       Autowired是自动注入,自动从spring的上下文找到合适的bean来注入
       Resource用来指定名称注入
       Qualifier和Autowired配合使用,指定bean的名称
       Service,Controller,Repository分别标记类是Service层类Controller层类数据存储层(dao)的类,spring扫描注解配置时,会标记这些类要生成bean,替代Xml配置的<bean id="xxx" class="xxx"/>
       Component是一种泛指,标记类是组件,spring扫描注解配置时,会标记这些类要生成bean。
上面的Autowired和Resource是用来修饰字段,构造函数,或者设置方法,并做注入的。而Service,Controller,Repository,Component则是用来修饰类,标记这些类要生成bean。

3.首先解释下MVC结构:
       表示层(V)调用控制层(Control),控制层调用业务层(Service),业务层调用数据访问层(Dao)。
       初期也许都是new对象去调用下一层,比如你在业务层new一个DAO类的对象,调用DAO类方法访问数据库,这样写是不对的,因为在业务层中是不应该含有具体对象,最多只能有引用,如果有具体对象存在,就耦合了。当那个对象不存在,我还要修改业务的代码,这不符合逻辑。好比主板上内存坏了,我换内存,没必要连主板一起换。我不用知道内存是哪家生产,不用知道多大容量,只要是内存都可以插上这个接口使用。这就是MVC的意义。

java中dao层和service层的区别是什么?
比说你现在用的是SSH框架,做一个用户模块:
     1、假设现在你做这个功能会用到user表,那么你前台的页面访问action,action再去调用用户模块service,service的实现类就去调用userDAO。
     2、也就是说DAO一定是和数据库的每张表一一对应,而service则不是。明白的没?其实你一个项目一个service和一个DAO其实也一样可以操作数据库,只不过那要是表非常多,出问题了,那找起来多麻烦,而且太乱了
     3、好处就是你的整个项目非常系统化,和数据库的表能一致,而且功能模块化,这样以后维护或者改错比较容易,性能也高一些。

4.扯远了,下面通过例子进行学习注解注入:

通过下面的例子理解控制反转:
        CarService里需要有一个CarDa的对象,但不是在CarService里new产生CarDao对象,而是在需要的时候,通过spring容器产生。那么什么时候是需要的时候呢?在service.addCar()执行时,就用到了CarDao对象,这时spring会通过配置给CarService注入一个对象。这就是依赖注入或者控制的反转。


目录结构:



1、建立dao层,给它添加@Repository注解 (注:dao类不需实现某个接口,当然实现接口也可以)
     dao是数据访问层,一般在dao层操作数据库。
package annotation;import org.springframework.stereotype.Repository;@Repositorypublic class CarDao {    public void insertCar(String car) {        String insertMsg = String. format( "inserting car %s", car);        System. out.println( insertMsg);    }}



2、Service层,@Service注解,在这个类中定义CarDao的字段,并通过Autowired来修饰此字段,这样上面定义的CarDao类的实例就会自动注入到CarService的实例中了。
(注:service类不需实现某个接口,当然实现接口也可以)
package annotation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class CarService {    @Autowired    private CarDao carDao;    public void addCar(String car) {        this. carDao.insertCar( car);    }}



3、下面我们在App.java中使用上面测试下注解注入:
package annotation;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class App {    public static void main( String[] args ){        ApplicationContext appContext = new AnnotationConfigApplicationContext("annotation");//扫描package寻找beans        CarService service = appContext.getBean(CarService.class);//利用java反射获取beans,spring获取bean可以通过类型、名称获取,此处通过类型来获取的        service.addCar( "宝马2");    }}



     在上面的main方法中首先我们初始化了appContext,他是AnnotationConfigApplicationContext,它的构造函数接受一个package的名称,来限定要扫描的package。然后就可以通过appContext的getBean方法获得CarService的实例了,利用了java的反射机制。

运行结果:


上面的例子非常简单,单纯的使用AnnotationConfigApplicationContext就可以了,但是在实际项目中情况往往没有这么简单,还是需要spring配置文件的。
原创粉丝点击