Spring学习笔记二

一、注解开发

spring轻代码重配置,就导致了配置繁重,影响开发的效率,注解开发代替xml的配置文件,可以简化配置。spring原始注解主要是代替 < Bean>标签的配置。
主要分为基于xml的自动装配基于注解的自动装配

二、基于xml的自动装配

基于xml的自动装配需要为每一个类需要自动装配的类中设置对应的set方法,否则会装配失败。

2.1 定义Controller,Service,Dao三层进行模拟

UserController

public class UserController {
	//自动装配userService
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void saveUser(){
        userService.saveUser();
    }

}

UserService

public interface UserService {
    void saveUser();
}

UserService实现类UserServiceImpl

public class UserServiceImpl implements UserService {
	//自动装配userDao
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void saveUser() {
        userDao.saveUser();
    }
}

UserDao

public interface UserDao {
    void saveUser();
}

UserDao实现类UserDaoImpl

public class UserDaoImpl implements UserDao {
    @Override
    public void saveUser() {
        System.out.println("保存成功");
    }
}

2.2 xml配置文件

spring-autowire.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--
	    autowire="byType|byName"
		    byType:根据对象类型装配
		    byName:根据名称装配
    -->
    <bean id="userController" class="com.lx.controller.UserController" autowire="byType">
<!--        <property name="userService" ref="userService"></property>-->
    </bean>
    <bean id="userService" class="com.lx.service.impl.UserServiceImpl" autowire="byName">
<!--        <property name="userDao" ref="userDao"></property>-->
    </bean>
    <bean id="userDao" class="com.lx.dao.impl.UserDaoImpl"></bean>
</beans>

没有学自动装配之前是通过set注入的形式对属性进行赋值,自动装配只需要设置autowire属性即可。

2.3 测试

测试类

public class AutoWireByXmlTest {
    /*
    * 自动装配:
        根据指定的策略,在I0C 容器中匹配某个bean,自动为bean中的类类型的属性或接口类型的属性赋值
        可以通过bean标签中的autowire属性设置自动装配的策略
        自动装配的策略: 
        no,default: 表示不装配,即bean 中的属性不会自动匹配某个bean为属性赋值,此时属性使用默认值
        byType:根据要赋值的属性的类型,在I0C 容器中匹配某个bean,为属性赋值
        注意:
        a>若通过类型没有找到任何一个类型匹配的bean,此时不装配,属性使用默认值
        b>若通过类型找到了多个类型匹配的bean,此时会抛出异常: NoUniqueBeanDefinitionException
        总结:当使用byType 实现自动装配时,IOC容器中有且只有一个类型匹配的bean 能够为属性赋值
        * 3,byName: 将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean,为属性赋值
        *总结:当类型匹配bean有多个时, 此时可以使用byName实现自动装配
     * */
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-autowire.xml");
        UserController userController = context.getBean(UserController.class);
        userController.saveUser();
    }
}

三、基于注解的自动装配

基于注解的自动装配不需要设置set方法

3.1 开启组件扫描

    <!--启动组件扫描,指定对应扫描的包路径,该包及其子包下所有的类都会被扫描,加载包含指定注解的类-->
    <!--
    context :exclude- filter:排除扫描
    type:设置排除扫描的方式
    type= "annotation/assignable"
    annotation:根据注解的类型进行排除,expression需要设置排除的注解的全类名
    assignable:根据类的类型进行排除,expression需要设置排除的类的全类名
    context: include-filter:包含扫描
    注意:需要在context: component - scan标签中设置use - default-filters= "false”
    use-default-filters="true" (默认) |所设置的包下所有的类都需要扫描,此时可以使用排除扫描
    use-default-filters= "false",所设置的包下所有的类都不需要扫描,此时可以使用包含扫描

    -->
    <context:component-scan base-package="org.lx">
<!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
<!--        <context:exclude-filter type="assignable" expression="org.lx.controller.UserController"/>-->
<!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
    </context:component-scan>
</beans>

3.2 IOC相关注解

@Component,@Controller,@Service ,@Repository
上述4个注解都是加到类上的。
他们都可以起到类似bean标签的作用。可以把加了该注解类的对象放入Spring容器中。
实际再使用时选择任意一个都可以。但是后3个注解是语义化注解。
如果是Service类要求使用@Service。
如果是Dao类要求使用@Repository
如果是Controllerl类(SpringMVC中会学习到)要求使用@Controller
如果是其他类可以使用@Component

  • @Component:将类标识为普通组件
  • @Controller:将类标识为控制层组件
  • @Service:将类标识为业务层组件
  • @Repository:将类标识为持久层组倒.
    通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名的首字母为小写的结果
    可以通过标识组件的注解的value属性值设置bean的自定义的id

3.3 示例

UserController

@Controller("userController")
public class UserController {
    @Autowired
    private UserService userService;
    public void saveUser(){
        userService.saveUser();
    }
}

UserService

public interface UserService {
    void saveUser();
}

UserServiceImpl

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    public void saveUser() {
        userDao.saveUser();
    }
}

UserDao

public interface UserDao {
    void saveUser();
}

UserDaoImpl

@Repository
public class UserDaoImpl implements UserDao {
    @Override
    public void saveUser() {
        System.out.println("保存成功");
    }
}

3.4 测试

public class IOCByAnnotationTest {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
        UserController controller = context.getBean("userController",UserController.class);
        controller.saveUser();
    }

}

3.5 DI相关注解

如果一个bean已经放入Spring容器中了。那么我们可以使用下列注解实现属性注入,让Spring容器帮我们完成属性的赋值。

  1. @Autowired

    实现自动装配功能的注解,加在要注入的成员变量上

    	@Service("userService")
    	@Data
    	@NoArgsConstructor
    	@AllArgsConstructor
    	public class UserServiceImpl implements UserService {
    		@Autowired
    	    private UserDao userDao;
    	    public void show() {
    	        userDao.show();
    	    }
    	}
    
    1. @Autowired注解能够标识的位置
      • 标识在成员变量上,此时不需要设置成员变量的set方法
      • 标识在set方法上
      • 标识在为当前成员变量赋值的有参构造上
    2. @Autowired注解的原理
      • 默认通过byType的方式,在IOC 容器中通过类型匹配某个bean为属性赋值
      • 若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果
        即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
      • 若byType和byName的方式都无妨实现自动装配,即I0C 容器中有多个类型匹配的bean
        且这些bean的id和要赋值的属性的属性名都不一致,此时抛异常: NoUniqueBeanDefinitionException
      • 此时可以在要赋值的属性上,添加一个注解@Qualifier
        通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值
        注意: 若IOC容器中没有任何一个类型匹配的bean, 此时抛出异常: NoSuchBeanDefinitionException
        在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
        可以将required设置为false,此时能装配则装配,无法装配则使用属性的默认值
  2. @Value

    主要用于String,Integer等可以直接赋值的属性注入。不依赖setter方法,支持SpEL表达式。

    @Service("userService")
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class UserServiceImpl implements UserService {
    	@Autowired
        private UserDao userDao;
        @Value("199")
        private int num;
        @Value("lx")
        private String str;
        @Value("#{19+3}")
        private Integer age;
        public void show() {
            userDao.show();
        }
    }
    
  3. @Qualifier

    如果相同类型的bean在容器中有多个时,单独使用@AutoWired就不能满足要求,这时候可以再加上@Qualifier来指定bean的名字从容器中获取bean注入。

        @Autowired
        @Qualifier("userDao2")
        private UserDao userDao;
    
  4. @Resource

    相当于@Autowired+ @Qualifier,按照名称进行注入,加在要注入的成员变量上

	    @Resource("userDao2")
	    private UserDao userDao;

四、xml配置文件相关注解

4.1 @Configuration

标注在类上,表示当前类是一个配置类。我们可以用注解类来完全替换掉xml配置文件。
注意:如果使用配置类替换了xml配置,spring容器要使用:AnnotationConfigApplicationContext
例如:

@Configuration
public class ApplicationConfig {
}

4.2 @ComponentScan

可以用来代替context:component-scan标签来配置组件扫描。
basePackages属性来指定要扫描的包。
注意要加在配置类上。

@Configuration
@ComponentScan(basePackages = "com.lx")//指定要扫描的包
public class ApplicationConfig {
}

4.3 @Bean

可以用来代替bean标签,主要用于第三方类的注入。
使用:定义一个方法,在方法中创建对应的对象并且作为返回值返回。然后在方法上加上@Bean注解,注解的value属性来设置bean的名称。
例如:

@Configuration
@ComponentScan(basePackages = "com.lx")
public class ApplicationConfig {
    @Bean("dataSource")
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUsername("root");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_db");
        druidDataSource.setPassword("root");
        return druidDataSource;
    }
}

注意事项:如果同一种类型的对象在容器中只有一个,我们可以不设置bean的名称

获取方式如下:

    public static void main(String[] args) {
        //创建注解容器
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		//根据对应类的字节码对象获取
        DataSource bean = app.getBean(DataSource.class);
        System.out.println(userService);
    }

4.4 @PropertySource

可以用来代替context:property-placeholder,让Spring读取指定的properties文件。然后可以使用@Value来获取读取到的值。

使用:在配置类上加@PropertySource注解,注解的value属性来设置properties文件的路径。
然后在配置类中定义成员变量。在成员变量上使用@Value注解来获取读到的值并给对应的成员变量赋值。


properties配置文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_db
jdbc.username=root
jdbc.password=root

读取文件并且获取值

@Configuration
@ComponentScan(basePackages = "com.lx")
@PropertySource("jdbc.properties")
public class ApplicationConfig {

    @Value("${jdbc.driver}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Bean
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUsername(username);
        druidDataSource.setUrl(url);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }

}

注意事项:使用@Value获取读到的properties文件中的值时使用的是${key},而不是#{key}。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝朽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值