利用annotation配置注入关系
为了更好的解释此类存在的意义,下面通过一段习惯性的开发进行问题的描述,例如:
现在有一个IAdminService服务层,这个服务层要调用的是IAdminDAO和IRoleDAO两个数据层操作,于是定义如下:
范例:定义数据层操作。
package com.Spring.Dao;public interface IAdminDAO {public boolean findLogin();}
和
package com.Spring.Dao;public interface IRoleDAO {public boolean findAll(); }
实现层:
package com.Spring.Dao.Imp;import com.Spring.Dao.IAdminDAO;public class AdminDAOImpl implements IAdminDAO {@Overridepublic boolean findLogin() {System.out.println("[IAdminDAO]public boolean findLogin()");return false;} }
和
package com.Spring.Dao.Imp;import com.Spring.Dao.IRoleDAO;public class RoleDAOImpl implements IRoleDAO {@Overridepublic boolean findAll() {System.out.println("[IRoleDAO]public boolean findAll()");return false;} }
最早的时候,这两个数据层的类一定要编写工厂类,单向现在不用编写工厂类了。
下面直接在appllicationContext.XML文件里面定义。
<bean id="adminDaoImpl" class="com.Spring.Dao.Imp.AdminDAOImpl"></bean><bean id="roleDaoImpl" class="com.Spring.Dao.Imp.RoleDAOImpl"></bean>
随后所有的数据层都要交给业务层操作,那么下面定义业务层操作:
package com.Spring.Service;public interface IAdminService {public boolean login(); }
下面定义实现层:
package com.Spring.Service.Impl;import com.Spring.Dao.IAdminDAO; import com.Spring.Dao.IRoleDAO; import com.Spring.Service.IAdminService;public class IAdminServiceImpl implements IAdminService {private IAdminDAO adminDao;private IRoleDAO roleDao;//setter是给依赖注入关系使用的。public void setAdminDao(IAdminDAO adminDao) {this.adminDao = adminDao;}public void setRoleDao(IRoleDAO roleDao) {this.roleDao = roleDao;}@Overridepublic boolean login() {this.adminDao.findLogin();this.roleDao.findAll();return false;} }
定义applicationContext.xml文件,配置彼此关系。
<bean id="adminDaoImpl" class="com.Spring.Dao.Imp.AdminDAOImpl"></bean><bean id="roleDaoImpl" class="com.Spring.Dao.Imp.RoleDAOImpl"></bean><bean id="adminServiceImpl" class="com.Spring.Service.Impl.IAdminServiceImpl"><property name="adminDao" ref="adminDaoImpl"></property><property name="roleDao" ref="roleDaoImpl"></property></bean>
代码写到此处,可以说最原始的操作完成了,所有的关系通过applicationContext.xml文件完成了,
package com.Spring.Demo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Spring.Service.IAdminService; import com.Spring.Service.Impl.IAdminServiceImpl;public class TestAdmin {public static void main(String args[]){ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext2.xml");IAdminService ia=ctx.getBean("adminServiceImpl",IAdminServiceImpl.class);ia.login();} }
执行结果:
此时最直观感受是,避免了工厂类的编写,的确节约了代码,但是反过来,问题又出现了,如果一个项目存在几百个DAO或Service。这种写法太累了。
在Spring之中,可以利用annotation完全简化以上操作。
范例:要增加新的命名空间。
在配置文件中勾选上context命名空间:
会发现配置代码中多了以下代码:
范例:设置annotation的支持包
<context:annotation-config/><context:component-scan base-package="com.Spring"/>
表示在“com.Spring”下所有程序支持annotation的配置。而在spring里面,针对于组件的annotation的配置
只提供三个注解定义(这三个注解定义的作用都一样,只是单词不同):
- @Component:主要用于定义组件,一般用于DAO上使用。
- @Service:主要用于定义组件,一般用于Service上用。
- @Repository:主要用于定义组件,一般用于Action上使用。
范例:修改xxxDAOImpl类:
package com.Spring.Dao.Imp; import org.springframework.stereotype.Component; import com.Spring.Dao.IAdminDAO;@Component public class AdminDAOImpl implements IAdminDAO {@Overridepublic boolean findLogin() {System.out.println("[IAdminDAO]public boolean findLogin()");return false;} }
和:
package com.Spring.Dao.Imp;import org.springframework.stereotype.Component;import com.Spring.Dao.IRoleDAO; @Component public class RoleDAOImpl implements IRoleDAO {@Overridepublic boolean findAll() {System.out.println("[IRoleDAO]public boolean findAll()");return false;} }
现在如果使用了注解定义组件,那么名称默认情况下就是类名称的结构形式:
比如:AdiminDAOImpl:则访问组件的名称就是“adminDaoImpl”。
范例:在service层上使用注解:
相比之前,这里的两个adminDao和roleDao的setter方法取消掉了,并且之前配置里面与setter配合使用,将会把如下的实例化作用的<bean>配置也去掉了,
<bean id="adminDaoImpl" class="com.Spring.Dao.Imp.AdminDAOImpl"></bean><bean id="roleDaoImpl" class="com.Spring.Dao.Imp.RoleDAOImpl"></bean><bean id="adminServiceImpl" class="com.Spring.Service.Impl.IAdminServiceImpl"><property name="adminDao" ref="adminDaoImpl"></property><property name="roleDao" ref="roleDaoImpl"></property></bean>
取而代之的是注解:@Resource,来代替上面的这两个属性,表示此为注入的资源。
package com.Spring.Service.Impl; import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.Spring.Dao.IAdminDAO; import com.Spring.Dao.IRoleDAO; import com.Spring.Service.IAdminService; @Service public class IAdminServiceImpl implements IAdminService { @Resource //表示此为注入的资源private IAdminDAO adminDao;@Resourceprivate IRoleDAO roleDao;@Overridepublic boolean login() {this.adminDao.findLogin();this.roleDao.findAll();return false;} }
此时AdminServiceImpl类的引用名称是:IAdminServiceImpl。因此使用的使用,使用getBean操作里面的bean名称也是这个,如下:
测试操作:
package com.Spring.Demo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Spring.Service.IAdminService; import com.Spring.Service.Impl.IAdminServiceImpl;public class TestAdmin {public static void main(String args[]){ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext2.xml");IAdminService ia=ctx.getBean("IAdminServiceImpl",IAdminServiceImpl.class);ia.login();} }
现在发现:利用annotation实现的注入操作,整个流程都是非常简化的,以后开发都是此类模式进行。