注解产生原因
1、传统spring的做法:使用xml来对bean进行注入和或者是配置aop、事物配置文件体积庞大,造成了配置文件的可读性和可维护性很低Java文件和xml不断切换,造成思维不连贯开发效率降低
2、引入注解的做法:通过@xxx让注解与Java Bean紧密结合既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。
构造IOC容器的两种方式
1、使用配置文件
2、使用注解
用注解来向Spring容器注册Bean。需要在配置文件中注册<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>,默认启用注解的支持
,<context:annotation-config /> 可省略。
<?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:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- <context:annotation-config /> --> <!-- 扫描这个包的所有组件 --> <context:component-scan base-package="ecut.aop.annotation" /> <!-- 为 注解 提供 自动产生 代理对象的 支持 --> <aop:aspectj-autoproxy proxy-target-class="true" /> </beans>
base-package所指定的包及其子包会被扫描(多个包可用逗号分隔),只要类中带有特殊的注解将会被自动注入
常用的注解
1、标注组件的
- @org.springframework.stereotype.Controller : 专门用来 标注 控制层的组件
package ecut.aop.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; /** * 控制层 ( Controller ) : 对 表示层 的用户操作 做出响应 * 实现技术可以是: Servlet 、Struts 、Spring MVC * @Controller("sc") value ="sc" 相当于bean的名称是sc,默认名称是 studentController */ @Controller public class StudentController { @Autowired @Qualifier( "studentService" ) private StudentService studentService ; public String regist( Student s ){ System.out.println( "StudentController # regist ( Student ) " ); studentService.save( s ); return "success" ; } public String logout() { throw new RuntimeException( "抛出异常" ); } public StudentService getStudentService() { return studentService; } public void setStudentService(StudentService studentService) { this.studentService = studentService; } }
扫描到注解@Controller相当于在配置文件中<bean id="studentController" class="ecut.aop.annotation.StudentController" />增加这段配置。bean的id属性即名称若在注解中没有指定则默认是类名首字母小写后的名称例如StudentController类所默认的名称是studentController,若通过注解中的value指定了名称,则与此保持一致。
- @org.springframework.stereotype.Service : 专门用来标注 业务逻辑层 的组件
package ecut.aop.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 业务逻辑层 ( Service ) 具体的业务逻辑 */ @Service public class StudentService { @Autowired private StudentDao studentDao ; public void save( Student s ) { System.out.println( "StudentService # save ( Student ) " ); studentDao.persist( s ); } public StudentDao getStudentDao() { return studentDao; } public void setStudentDao(StudentDao studentDao) { this.studentDao = studentDao; } }
@Service相当于在配置文件中增加<bean id="studentService" class="ecut.aop.annotation.StudentService" />
- @org.springframework.stereotype.Repository : 专门用来 标注 数据访问层 的 组件
package ecut.aop.annotation; import org.springframework.stereotype.Repository; /** * 数据访问层 ( Repository ) 专门负责访问数据库 * DAO :Data Access Object , 数据访问对象 * 对象封装数据 */ @Repository public class StudentDao { public void persist( Student s ) { System.out.println( "StudentDao 的 persist 方法提示你: 保存 "+ s.getName() ); } }
@Repository相当于在配置文件中增加<bean id="studentDao" class="io.spring.aop.annotation.StudentDao" />
- @org.springframework.stereotype.Component : 可以标注任意的组件
package ecut.aop.annotation; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component @Aspect public class StudentAspect { ....... }
当不能确定到底是 Controller 、Service 、Repository 中的那种类型时,适用。
2、标注自动装备的
- @org.springframework.beans.factory.annotation.Autowired : 默认按照类型对某个属性进行装配
package ecut.aop.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 业务逻辑层 ( Service ) 具体的业务逻辑 */ @Service public class StudentService { @Autowired private StudentDao studentDao ; .............................. }
相当于 <bean id="studentService" class="ecut.aop.annotation.StudentService" autowire="byType"/>,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去。
- @org.springframework.beans.factory.annotation.Qualifier 与 Autowired 连用一起实现 按照名称进行自动装配
package ecut.aop.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; /** * 控制层 ( Controller ) : 对 表示层 的用户操作 做出响应 * 实现技术可以是: Servlet 、Struts 、Spring MVC * @Controller("sc") value ="sc" 相当于bean的名称是sc,默认名称是 studentController */ @Controller public class StudentController { @Autowired @Qualifier( "studentService" ) private StudentService studentService ; ........ }
相当于 <bean id="studentController" class="ecut.aop.annotation.StudentController" autowire="byName"/>或者 <bean id="studentController" class="ecut.aop.annotation.StudentController" p:studentService-ref="studentService"/>
-
@javax.annotation.Resource:@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配指定了name或者type则根据指定的类型去匹配bean指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
3、@Resource和@Autowired注解的区别
- 默认匹配的方式不同:@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配。
- 所属架构不同:@Autowired是Spring的注解,@Resource是J2EE的注解(Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合)
转载请于明显处标明出处: