鉴于之前的博文中都是通过在xml中对bean进行配置的方式注入的,又加上博友的要求,决定对注解方式进行一个简单的讲解,这里不会涉及太复杂的程序,因为本文的目的是让看到这篇博文的广大博友能懂,而不是云里雾里的怎么也看不明白。
1. @Controller:标注一个控制器组件的类。
2. @Service:标注一个业务逻辑组件的类。
3. @Repository:标注一个Dao组件的类。
4. @Component:标注一个普通的类。
这几个注解主要用于标注Spring要进行实例化的类,一旦在某个类的上面标注了这样的注解,如果是单例模式的话,那么Spring在初始化的时候,就会将这些类实例化,而对于非单例模式的类,不取决于Spring容器本身,往往是客户端进行请求的时候,进行创建实例(Spring创建的),这些在之前的博文中已经进行过说明,请参考Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程。
5. @Resource:按照名称(name)进行注入。该注解属于jdk中的注解,但是在项目中使用比较广泛。
6. @Autowired:按照类型匹配自动注入。
这里的两个注解主要用于为类中属性注入值。两个注解可以将(上面四个注解标注的类在Spring中实例化后的对象)注入到某些类的属性中。
7. @Scope("prototype"):默认的情况下是产生单例对象,在Scope的里面传了prototype的参数后,表明该类不是单例的,而是"多例的",不知道这么解释标准不标准,读者可以纠正。
8. @PostConstruct:指定bean的初始化方法与之前博文中配置文件指定的initMethod作用相同(Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程),Spring会在Bean的依赖注入完成后回调这个方法。
9. @PreDestroy:指定bean的销毁之前的方法与Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程这篇博文中配置文件指定的destroyMethod的作用是一样的,他会在bean销毁之前调用。
另外:
10: @Lazy:用于指定该类是否取消预初始化。指定参数boolean型true即可,下面不在赘述,这个注解比较简单。
11: @DependsOn:可以修饰类或者方法,用于强制初始化一些bean,例如:@DependsOn({"wy", "wangyang"}),这样在初始化之前会强制初始化里面的bean.
用注解进行自动注入bean的前提是在配置文件中配置了自动注入的支持。
<span style="font-size:14px;"><?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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd "> <!-- 配置自动扫描: 命名空间中记得加入几个 xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd --> <context:component-scan base-package = "com.siti.spring20160316"/> </beans></span>
控制器组件:
用到了@Controller、@Scope、@Resource、@Autowired四个注解,如果这里没有被注入进来的话,会在调用的地方抛出空指针异常,如果不抛出空指针就说明bean已经被注入进来了。
package com.siti.spring20160316; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; @Controller @Scope("prototype") public class UserAction { @Resource private UserService userService; @Autowired private Utils utils; public boolean login(String userName, String password){ System.out.println("UserAction--login"); if(utils.check(userName)){ if(userService.login(userName, password)){ return true; } } return false; } }
在这里说明下,一般我们开发中比较喜欢用接口,这里是为了看起来清楚没有采用接口的形式,避免读者看的云里雾里搞不清楚流程。
这里主要用到的注解有@Service(标注业务逻辑层)、@PostCustruct(标注的方法相当于initMethod)、@PreDestroy(标注的方法相当于destroyMethod)
package com.siti.spring20160316; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import org.springframework.stereotype.Service; /** * * @ProjectName SpringBlob * @ClassName UserService * @Description 一般情况下,都是采用接口的,这里没有使用接口,便于读者直接看清楚调用关系 * @author wy * @date 2016-3-16 * */ @Service public class UserService { @Resource private UserDao userDao; public boolean login(String userName, String password){ System.out.println("UserService--login"); if(userDao.isExist(userName, password)){ return true; } return false; } @PostConstruct public void init(){ System.out.println("UserService--init"); } @PreDestroy public void destroyMethod(){ System.out.println("UserService--destroyMethod"); } }DAO层
主要用到的注解有@Repository
由于这里属于模拟没有加入连接数据库部分的持久化操作,请见谅。
package com.siti.spring20160316; import org.springframework.stereotype.Repository; @Repository public class UserDao { public boolean isExist(String userName, String password){ System.out.println("UserDao--isExist"); if("wy".equals(userName)){ return true; } return false; } }
第一个输出比较两个得到的对象是不是同一个对象。读者可以自己检验其他的几个对象是不是同一个。因为UserAction类标注了@Scope的注解并指定其类型为prototype,那么这里应该是不一样的,输出false
package com.siti.spring20160316; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainTest { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160316.xml"); UserAction action = (UserAction) context.getBean("userAction"); UserAction action2 = (UserAction) context.getBean("userAction"); System.out.println("这两个对象是否是同一个对象:" + action.equals(action2)); boolean bool = action.login("wy", "******"); if(bool){ System.out.println("登录成功!"); }else{ System.out.println("登录不成功!"); } context.registerShutdownHook(); } }
这里只是自己写了个注解,但是没有解析类是没办法去用的,读者可以试试看能不能自己写出他的处理类,可以共同交流下。
package com.siti.spring20160316; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)// 运行期间注入 @Target({ElementType.FIELD, ElementType.METHOD})// 可以标注在哪里,这里是属性和方法上 public @interface MyAutowired { // 参数 public String name() default ""; }