四、注解
(1).使用注解定义bean
-
1.注解方式
-
a.使用@Component在Dao、Service等层进行设定
-
@Repository==》数据层bean
//@Component("bookDao") @Repository("bookDao") public class BookDao {...}
-
@Service==》业务层bean
//@Component("bookDao") @Service("bookService") public class BookServiceImpl implements BookService {...}
-
@Controller==》控制器层
//@Component("bookDao") @Controller public class BookController {...}
-
b.在配置文件中新开启一个命名空间,具体步骤如数据源管理所示,并使用context:component-scan 进行扫描注解所设定的单个或多个(使用,分割)类路径
-
//单个 <context:component-scan base-package="Dao"></context:component-scan> //多个 <context:component-scan base-package="Dao,Service"></context:component-scan>
-
c.在业务层进行业务逻辑处理
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml"); BookDao bookDao = (BookDao) ctx.getBean("bookDao"); System.out.println(bookDao); BookServiceImpl bookService = (BookServiceImpl) ctx.getBean("bookService"); System.out.println("---------------"); System.out.println(bookService);
-
-
-
使用纯注解进行定义
-
使用@Configuration指定该类为配置类,@ComponentScan()进行bean指定类路径的扫描
-
@Configuration @ComponentScan({"Dao","Service"}) public class SpringConfig {...}
-
※※※采取纯注解方式定义bean时读取Spring核心配置文件初始化容器对象变成了读取Java配置类初始化容器对象
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
-
2.bean的作用范围
-
在类的声明上方使用@Scope进行注解,参数为singleton(默认单例)/prototype(多例)
@Repository @Scope("singleton") public class BookDao {...}
-
-
3.bean的生命周期
-
使用@PostConstructor在自定义初始化方法上进行注解,会在bean的构造方法后执行
@PostConstruct public void init(){ System.out.println("init..."); }
-
使用@PreDestroy在自定义销毁方法上进行注解,会在IoC容器关闭前执行
@PreDestroy public void destroy(){ System.out.println("destroy..."); }
-
(2)注解开发依赖注入
-
1.引用类型自动装配
-
a.使用@Autowired或则配置文件进行依赖注入前报错NullPointerException==》注入失败
-
b.使用@Autowired进行依赖注入
@Autowired private BookDao bookDao;
-
-
-
c.问题:如果出现多个同样类型的bean,会根据名称自动装配,如果bean命名一致,会报出错误NoUniqueBeanDefinitionException,使用@Qualifier和@Repository指定所需的bean进行注入,@qualifier必须和@Autowired配合使用
@Autowired @Qualifier("bookDao") private BookDao bookDao; @Repository("bookDao") public class BookDaoImpl implements BookDao{ public void save() {System.out.println("book Dao...");} } @Repository("bookDao2") public class BookDaoImpl2 implements BookDao{{ public void save() {System.out.println("book Dao...22222222");} }
-
2.基本类型自动装配
-
a.使用@Value进行装配
@Value("基本类型的自动装配@Value") private String name;
-
b.从外部文件对基本类型进行自动装配
-
使用@PropertySource在SpringConfig文件中加载外部文件
@PropertySource("myProperties.properties")
-
使用@Value("${}")进行获取外部文件中对应的值
@Value("${name}") private String name;
-
-
-
※※※注意:在使用@PropertySource()指定文件名时,不可像使用配置文件时location中的所有文件即不可使用*.properties
-
-
3.使用注解管理第三方bean
-
a.实现思路==》不推荐使用
-
编写一个方法用于获取待管理第三方bean,并且该方法使用@Bean注解进行设定==工厂模式
public DataSource druidDataSource(){ DruidDataSource dataSource = new DruidDataSource(); //DataSource接口无set方法 dataSource.setDriverClassName("com.mysql.jdbc.driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/spring_db"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; }
-
使用@Bean==》表示当前方法返回值为bean对象
@Bean public DataSource druidDataSource(){...}
-
获取并操作bean
DataSource dataSource = ctx.getBean(DataSource.class); System.out.println(dataSource);
-
-
b.优化方式一(扫描式):抽离+扫描==》不推荐使用
-
1.将其所编写的方法抽离出来,单独成为一个配置类,与其spring的配置类进行区分
@Configuration public class JdbcConfig { @Bean public DataSource druidDataSource(){ return new DruidDataSource(); } }
-
在Spring的配置类中使用@ComponentScan扫描该配置类
@ComponentScan("config")
-
-
c.优化方式二(导入式):抽离+导入==》推荐使用
-
同优化方式一.1
-
在Spring的配置类中使用@Import导入该配置类
@Import(JdbcConfig.class)
-
-
-
4.从外部文件获取资源为第三方bean注入
-
a.定义外部文件
jdbc.driver = com.mysql.jdbc.drive jdbc.url = jdbc:mysql://localhost:3306/spring_db jdbc.username = root jdbc.password = root
-
b.在spring配置类中使用@PropertySource加载外部文件资源
@PropertySource("jdbc.properties")
-
c.在jdbc的配置类中使用${}读取资源
dataSource.setDriverClassName("${jdbc.driver}"); dataSource.setUrl("${jdbc.url}"); dataSource.setUsername("${jdbc.username}"); dataSource.setPassword("${jdbc.password}");
-
-
5.配置开发和注解开发的比较