Bean配置形式:
①. 基于 XML 文件的方式
②. 基于注解的方式
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~
①. 基于 XML 文件的方式
applicationContext.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">
<!-- 配置Bean -->
<bean id="person" class="com.baidu.spring.beans.test.Person">
<property name="name" value="LiLei"></property>
</bean>
</beans>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~
②. 基于注解的方式
(1). 在classPath 中扫描组件:
com.baidu.beans.annotation 基包 下的类
TestObject.java
package com.baidu.beans.annotation;
import org.springframework.stereotype.Component;
@Component
public class TestObject {
}
测试方法:TestSpringAnnotationBeans.java
package com.baidu.beans.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.baidu.beans.annotation.controller.UserController;
import com.baidu.beans.annotation.repository.UserRepository;
import com.baidu.beans.annotation.servlice.UserService;
public class TestSpringAnnotationBeans {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_annotation.xmll.xml");
// TestObject to = (TestObject) applicationContext.getBean("testObject");
// System.out.println(to);
//
// UserController uc = (UserController) applicationContext.getBean("userController");
// System.out.println(uc);
//
// UserService us = (UserService) applicationContext.getBean("userService");
// System.out.println(us);
UserRepository ur = (UserRepository) applicationContext.getBean("userRepository");
System.out.println(ur);
}
}
com.baidu.beans.annotation.controller下的类
UserController.java
package com.baidu.beans.annotation.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
public void execute(){
System.out.println("UserController execute....");
}
}
com.baidu.beans.annotation.servlice下的类
package com.baidu.beans.annotation.servlice;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void add() {
System.out.println("UserService add....");
}
}
com.baidu.beans.annotation.repository 下的类
UserRepository.java
package com.baidu.beans.annotation.repository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository {
void save();
}
UserRepositoryImpl.java
package com.baidu.beans.annotation.repository;
import org.springframework.stereotype.Repository;
/**
* Spring 有默认的命名策略:使用非限定类名,只一个字母小写,
* 也可以咋注解中通过vale 属性值标识组件的名称 ,如:@Repository("userRepository")
*/
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
@Override
public void save() {
System.out.println("UserRepositoryImpl Save....");
}
}
基于注解的方式配置bean
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--~~~~~~~~~~~~~~~~~~~~ 指定Spring IOC容器扫描的包 ~~~~~~~~~~~~~~~~~~~~-->
<!--
resource-pattern:指定扫描那个特定包下的资源,其他的子包将不被扫描
如:resource-pattern="repository/*.class" 将只能扫描repository包下的资源,
其他的兄弟包下的资源将不会被扫描
<context:component-scan base-package="com.baidu.beans.annotation"
resource-pattern="repository/*.class"></context:component-scan>
-->
<!-- context:exclude-filter 子节点: 指定排除那些指定表达式的组件
<context:component-scan base-package="com.baidu.beans.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
-->
<!--
context:include-filter 子节点: 指定只包含那些指定表达式的组件 ,
但是,这是需要配置一个 use-default-filters="false"
-->
<context:component-scan base-package="com.baidu.beans.annotation" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>
运行结果:
Ⅰ. 基本情况:仅配置基本情况,不添加任何限制条件
<context:component-scan base-package="com.baidu.beans.annotation"></context:component-scan>
运行结果:
com.baidu.beans.annotation.TestObject@f395158
com.baidu.beans.annotation.controller.UserController@7c0b7036
com.baidu.beans.annotation.servlice.UserService@52f428d9
com.baidu.beans.annotation.repository.UserRepositoryImpl@1ba5e91b
Ⅱ. 第一种情况:resource-pattern:指定扫描那个特定包下的资源,其他的子包将不被扫描
<context:component-scan base-package="com.baidu.beans.annotation"
resource-pattern="repository/*.class"></context:component-scan>
运行结果: 其他的bean 不被扫描
com.baidu.beans.annotation.repository.UserRepositoryImpl@7a05393a
Ⅲ. 第二种情况:context:exclude-filter 子节点: 指定排除那些指定表达式的组件
<context:component-scan base-package="com.baidu.beans.annotation">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
运行结果: 当获取UserRepository 时抛出错误
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userRepository' is defined
com.baidu.beans.annotation.TestObject@3448cbd6
com.baidu.beans.annotation.controller.UserController@173e696b
com.baidu.beans.annotation.servlice.UserService@27afbb9
<context:component-scan base-package="com.baidu.beans.annotation" use-default-filters="true">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
运行结果:
a. 如果use-default-filters="true", 则既是配置context:include-filter 还是使用的默认的bean即Ⅰ. 基本情况的配置情况
com.baidu.beans.annotation.TestObject@a54d24d
com.baidu.beans.annotation.controller.UserController@46bac287
com.baidu.beans.annotation.servlice.UserService@f395158
com.baidu.beans.annotation.repository.UserRepositoryImpl@7c0b7036
b. 如果use-default-filters="false",则 才能使用只包含哪些指定表达式的组件com.baidu.beans.annotation.repository.UserRepositoryImpl@5a05fffe
AutowiredAnnotationBeanPostProcessor 是bean 的后置处理器
1. 建立持久化类之间的关联关系:
TestObject.java
package com.baidu.beans.annotation;
import org.springframework.stereotype.Controller;
@Controller
public class TestObject {
}
UserController.java
package com.baidu.beans.annotation.controller;
import org.springframework.stereotype.Controller;
import com.baidu.beans.annotation.servlice.UserService;
@Controller
public class UserController {
private UserService userService;
public void execute(){
System.out.println("UserController execute....");
userService.add();
}
}
接口:UserRepository.java
package com.baidu.beans.annotation.repository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository {
void save();
}
接口:UserRepository 的实现类:UserRepositoryImpl.java
package com.baidu.beans.annotation.repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.baidu.beans.annotation.TestObject;
/**
* Spring 有默认的命名策略:使用非限定类名,只一个字母小写,
* 也可以咋注解中通过vale 属性值标识组件的名称 ,如:@Repository("userRepository")
*/
@Repository
public class UserRepositoryImpl implements UserRepository {
private TestObject testObject;
public void save() {
System.out.println("UserRepositoryImpl Save....");
System.out.println(testObject);
}
}
UserService.java
package com.baidu.beans.annotation.servlice;
import org.springframework.stereotype.Service;
import com.baidu.beans.annotation.repository.UserRepository;
@Service
public class UserService {
private UserRepository userRepository;
public void add() {
System.out.println("UserService add....");
userRepository.save();
}
}
配置bean
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.baidu.beans.annotation"></context:component-scan>
</beans>
测试方法:
package com.baidu.beans.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.baidu.beans.annotation.controller.UserController;
public class TestSpringAnnotationBeans {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_annotation.xml");
UserController uc = (UserController) applicationContext.getBean("userController");
System.out.println(uc);
uc.execute();
}
}
在上面的基础上运行:
@Autowired 注解自动装配具有兼容类型的单个 Bean属性
构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解
(1). 当我们把 @Autowired 分别加到 普通的字段上
package com.baidu.beans.annotation.servlice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baidu.beans.annotation.repository.UserRepository;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void add() {
System.out.println("UserService add....");
userRepository.save();
}
}
package com.baidu.beans.annotation.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.baidu.beans.annotation.servlice.UserService;
@Controller
public class UserController {
@Autowired
private UserService userService;
public void execute(){
System.out.println("UserController execute....");
userService.add();
}
}
2. 当我们把 @Autowired 分别加到 set方法上
package com.baidu.beans.annotation.servlice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baidu.beans.annotation.repository.UserRepository;
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void add() {
System.out.println("UserService add....");
userRepository.save();
}
}
这是因为IOC容器中有 userRepository. userService 等对应bean ,才可以想上面运行,如果IOC容器没有响应的bean 呢?
package com.baidu.beans.annotation.repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.baidu.beans.annotation.TestObject;
/**
* Spring 有默认的命名策略:使用非限定类名,只一个字母小写,
* 也可以咋注解中通过vale 属性值标识组件的名称 ,如:@Repository("userRepository")
*/
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
@Autowired
private TestObject testObject;
public void save() {
System.out.println("UserRepositoryImpl Save....");
System.out.println(testObject);
}
}
去除IOC 容器中的testObject 的bean
运行结果:
设置:@Autowired(required=false)
package com.baidu.beans.annotation.repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.baidu.beans.annotation.TestObject;
/**
* Spring 有默认的命名策略:使用非限定类名,只一个字母小写,
* 也可以咋注解中通过vale 属性值标识组件的名称 ,如:@Repository("userRepository")
*/
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository {
@Autowired(required=false)
private TestObject testObject;
public void save() {
System.out.println("UserRepositoryImpl Save....");
System.out.println(testObject);
}
}
如果IOC容器中有好几个相匹配的bean 会怎么样呢?
UserJdbcRepository.java 实现UserRepository 接口
package com.baidu.beans.annotation.repository;
import org.springframework.stereotype.Repository;
@Repository
public class UserJdbcRepository implements UserRepository {
@Override
public void save() {
System.out.println("UserJdbcRepository save...");
}
}
运行结果:
为什么没有问题呢?
因为在UserService 中的setUserRepository () 放好有一个实现了被配置了()
如果我们去掉 UserRepositoryImpl 中的userRepository,会怎么样呢?
除了这样配置以外还有下面几种配置方式: