使用注解配置依赖注入

1.为什么要使用Spring注解?

传统的Spring做法是使用.xml文件来对bean对象进行注入。
会导致的问题:
(1)如果所有的内容都配置在.xml文件中,那么.xml文件会十分庞大,配置文件的可读性和可维护性变得很低。
(2)如果在开发过程中.java文件和.xml文件之间不断来回切换,是一件麻烦的事情,开发效率降低。

为了解决这两个问题,Spring引入注解,通过“@xxx”的方式,让注解和Java Bean 紧密结合。大大减少配置文件,又增加了Java Bean的可读性和内聚性。

Java Bean是一个遵循特定写法的Java类。
具有的特点:
(1)这个Java类必须有一个无参的构造函数
(2)属性必须私有化
(3)提供getter和setter方法
(4)实现serializable接口

2.注解的使用

1.导包或者是添加依赖包(maven)
2.需要在配置文件中添加一个约束:contenxt

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context  https://www.springframework.org/schema/context/spring-context.xsd

3.配置扫描组件

 <!--自动扫描包下的注解-->
    <context:component-scan base-package="com.msj.pojo"/>

4.JavaBean类(User.java)
在User类上面添加一个注解@Controller

package demo05.com.msj;

import org.springframework.stereotype.Controller;

@Controller("users")
public class User {
    private String username = "www";
    private Integer age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

5.测试

public class Test05 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/com/msj/bean05.xml");
        User users = (User)context.getBean("users");
        System.out.println(users.getUsername());

    }
}

3.IOC注入

1.可以不用提供set方法,直接在属性名上添加一个@Value
2.有set方法可以直接在set方法上面加上@Value,这样也可以把值注入

@Controller("users")
public class User {
    //在属性上添加 @Value,可以不用添加set方法
    @Value("eee")
    private String username;
    private Integer age;

    public String getUsername() {
        return username;
    }

//    public void setUsername(String username) {
//        this.username = username;
//    }

    public Integer getAge() {
        return age;
    }

  //在set方法上面加上 @Value
    @Value("23")
    public void setAge(Integer age) {
        this.age = age;
    }
}

4.常用注解

Spring部分

1. 声明bean的注解
(1)@Component 组件,没有明确的角色
(2)@Service 在业务逻辑层使用(Service层)
(3)@Repository 在数据访问层使用 (Dao层)
(4)@Controller 控制器的声明
2. 注入bean的注解
(1)@Autowired
(2)@Resource(jdk的注解)
都可以注解在set方法和属性上,推荐注解在属性上

  • 共同点
    两种都可以写在字段和setter方法上,两者如果都写在字段上 ,那么就不需要再写在setter方法上
  • 不同点
    (1)@Autowired
    @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
    该注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。
public class TestServiceImpl {
    // 下面两种@Autowired只要使用一种即可
    @Autowired
    private UserDao userDao; // 用于字段上
    
    @Autowired
    public void setUserDao(UserDao userDao) { // 用于属性的方法上
        this.userDao = userDao;
    }
}

如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 
}

(2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。
@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

public class TestServiceImpl {
    // 下面两种@Resource只要使用一种即可
    @Resource(name="userDao")
    private UserDao userDao; // 用于字段上
    
    @Resource(name="userDao")
    public void setUserDao(UserDao userDao) { // 用于属性的setter方法上
        this.userDao = userDao;
    }
}
  • 总结
    (1)当一个接口只有一个实现类,推荐使用@Autowired,默认byType注入,不一定 真的byType,可以修改为byName。
    (2)当一个接口有多个实现类,推荐使用@Resource,默认byName注入。
    3. java配置类相关的注解
    (1)@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法。

(2)@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)
User.java

public class User {
    //在属性上添加@Value,可以不用添加set方法
    private String username;
    private Integer age;

    public String getUsername() {
        return username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

AppConfig.java 配置类,替代.xml文件

@Configuration
public class AppConfig {
    @Bean("u")
    public User user(){
        User user = new User();
        user.setUsername("ccc");
        user.setAge(12);
        return user;
    }
}

测试类
使用AnnotationConfigApplicationContext

public class Test05 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        User user = (User)context.getBean("u");
        System.out.println(user.getUsername()+"--"+user.getAge());
    }
}

其中,AppConfig.java替代了bean.xml

 <bean id="users" class="demo05.com.msj.User">
       <property name="username" value="ddd"/>
       <property name="age" value="11"/>
   </bean>

(3)@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)
(4)@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)

ComponentScan做的事情就是告诉Spring从哪里找到bean。

4. 切面(AOP)相关的注解
(1)@Aspect 声明一个切面(类上)
(2)@After 在方法执行之后执行(方法上)
(3)@Before 在方法执行之前执行(方法上)
(4)@Around 在方法执行之前与之后执行(方法上)
(5)@PointCut 声明切点
5. Bean属性的支持
@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)
其设置类型包括:
(1)Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
(2)Protetype (每次调用新建一个bean),
(3)Request (web项目中,给每个http request新建一个bean),
(4)Session (web项目中,给每个http session新建一个bean)
6. @Value
@Value 为属性注入值(属性上)
7. 环境切换
(1)@Profile 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。(类或方法上)
8. @Qualifier 和 @Primary
当两个实现类实现了同一个接口,并且这两个实现类都被spring IoC容器所管理。那么在我们使用@Autowired注解该bean时候,spring如何知道开发者是要注入哪个bean呢?
(1)@Qualifier
@Qualifier指定需要注入的bean(该注解跟随在@Autowired后),灵活性强。
(2)@Primary
当优先使用哪个bean时,在该实现类上加上此注解。(该注解加在各个bean上)

SpringMVC部分

(1)@Controller 声明该类为SpringMVC中的Controller
(2)@RequestMapping 用于映射Web请求,包括访问路径和参数(类或方法上)
@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
(3)@ResponseBody 支持将返回值放在response内,而不是一个页面,通常用户返回json数据(返回值旁或方法上)
(4)@RequestBody 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
(5)@PathVariable 用于接收路径参数,比如
(6)@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容