2-Spring Bean管理

Spring Bean管理

Spring的工厂类

1.spring的工厂类管理

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout
    @Test
    /**
     * Spring的方式实现
     */
    public void demo2(){
        // 创建Spring的工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.sayHello();
    }

    @Test
    /**
     * 读取磁盘系统中的配置文件
     */
    public void demo3(){
        // 创建Spring的工厂类:
        ApplicationContext applicationContext = new FileSystemXmlApplicationContext("c:\\applicationContext.xml");
        // 通过工厂获得类:
        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.sayHello();
    }

2.Spring的Bean管理(XML方式)

1.使用类构造器实例化(默认无参数)
/**
 * Bean的实例化的三种方式:采用无参数的构造方法的方式
 */
public class Bean1 {
    public Bean1(){
        System.out.println("Bean1被实例化了...");
    }
}

* * *
public class SpringDemo2 {
    @Test
    public void demo1(){
        // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例:
        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
    }
 }

* * *
<!--第一种:无参构造器的方式-->
 <bean id="bean1" class="com.imooc.ioc.demo2.Bean1"/>
2.使用静态工厂方法实例化(简单工厂模式)
public class Bean2 {

}

* * *
/**
 * Bean2的静态工厂
 */
public class Bean2Factory {

    public static Bean2 createBean2(){
        System.out.println("Bean2Factory的方法已经执行了...");
        return new Bean2();
    }
}

* * *

public class SpringDemo2 {
    @Test
    public void demo2(){
        // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例:
        Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");
    }
}

* * *

<!--第二种:静态工厂的方式-->
<bean id="bean2" class="com.imooc.ioc.demo2.Bean2Factory" factory-method="createBean2"/>
3.使用实例工厂方法实例化(工厂方法模式)
/**
 * Bean的实例化三种方式:实例工厂实例化
 */
public class Bean3 {

}

* * *
/**
 * Bean3的实例工厂
 */
public class Bean3Factory {
    public Bean3 createBean3(){
        System.out.println("Bean3Factory执行了...");
        return new Bean3();
    }
}

* * *
public class SpringDemo2 {
    @Test
    public void demo3(){
    // 创建工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类的实例:
        Bean3 bean3 = (Bean3)applicationContext.getBean("bean3");
    }
}

* * *
<bean id="bean3Factory" class="com.imooc.ioc.demo2.Bean3Factory"/>
 <bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>

3.bean的常用配置

id和name

一般情况下,装配一个bean时,通过指定一个id属性作为Bean的名称,id属性在IOC容器中必须是唯一的。

如果Bean的名称中含有特殊字符,那么就需要name属性

class

class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例。

Bean的作用域

1.singleton:在SpringIOC容器中仅仅存在一个Bean实例,Bean以单例实例的方式存在。

2.prototype:每次调用getBean()时都会返回一个新的实例

3.request: 每次HTTP请求都会创建一个新的Bean,该作用域仅仅适用于WebApplicationContext环境。

4.session :同一个HTTP Session共享一个Bean,不同的Http Session使用不同的Bean.该作用域仅仅适用于WebAppliacationContext环境。

Bean的作用范围测试
public class Person {

}

* * *
public class SpringDemo3 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person persion1 = (Person)applicationContext.getBean("person");
        Person persion2 = (Person)applicationContext.getBean("person");

        System.out.println(persion1);
        System.out.println(persion2);
    }
 }
<!--Bean的作用范围=====================================-->
    <bean id="person" class="com.imooc.ioc.demo3.Person" scope="prototype"/>
Bean的生命周期
public class Man implements BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
    private String name;

    public void setName(String name) {
        System.out.println("第二步:设置属性");
        this.name = name;
    }

    public Man(){
        System.out.println("第一步:初始化...");
    }
    public void setup(){
        System.out.println("第七步:MAN被初始化了...");
    }

    public void teardown(){
        System.out.println("第十一步:MAN被销毁了...");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("第三步:设置Bean的名称"+name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:了解工厂信息");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性设置后");
    }

    public void run(){
        System.out.println("第九步:执行业务方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:执行Spring的销毁方法");
    }
}

* * *
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步:初始化前方法...");
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        System.out.println("第八步:初始化后方法...");

    }
}
<bean id="man" class="com.imooc.ioc.demo3.Man" init-method="setup" destroy-method="teardown">
        <property name="name" value="张三"/>
</bean>
<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"/>
public class SpringDemo3 {
    @Test
    public void demo2(){
       ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Man man = (Man)applicationContext.getBean("man");

        man.run();

        applicationContext.close();
    }
 }
增强jdk的动态代理
public interface UserDao {
    public void findAll();

    public void save();

    public void update();

    public void delete();
}

* * *
public class UserDaoImpl implements  UserDao {
    @Override
    public void findAll() {
        System.out.println("查询用户。。。");
    }

    @Override
    public void save() {
        System.out.println("保存用户。。。");
    }

    @Override
    public void update() {
        System.out.println("修改用户。。。");
    }

    @Override
    public void delete() {
        System.out.println("删除用户。。。");
    }
}

* * *
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //System.out.println("第五步:初始化前方法...");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        //System.out.println("第八步:初始化后方法...");
        if("userDao".equals(beanName)){
            Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if("save".equals(method.getName())){
                        System.out.println("权限校验===================");
                        return method.invoke(bean,args);
                    }
                    return method.invoke(bean,args);
                }
            });
            return proxy;
        }else{
            return bean;
        }

    }
}

* * *
public class SpringDemo3 {
    @Test
    public void demo3(){
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao)applicationContext.getBean("userDao");

        userDao.findAll();
        userDao.save();
        userDao.update();
        userDao.delete();
    }
 }
<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"/>

<bean id="userDao" class="com.imooc.ioc.demo3.UserDaoImpl"/>

5.Spring的属性注入(XML方式)

构造方法属性注入
  • 通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用.
  • 构造器注入在 元素里声明的属性
public class User {
    private String name;
    private Integer age;

    public User(String name,Integer age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 
* * *

public class SpringDemo4 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)applicationContext.getBean("user");
        System.out.println(user);
    }
  }
  
<!--Bean的构造方法的属性注入=============================-->
 <bean id="user" class="com.imooc.ioc.demo4.User">
    <constructor-arg name="name" value="张三" />
    <constructor-arg name="age" value="23"/>
 </bean>
属性setter方法注入
public class Person {
    private String name;
    private Integer age;

    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

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

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", cat=" + cat +
                '}';
    }
}

* * *
public class Cat {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

* * *
public class SpringDemo4 {
    @Test
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person)applicationContext.getBean("person");
        System.out.println(person);
    }
 }
<!--Bean的set方法的属性注入==============================-->
 <bean id="person" class="com.imooc.ioc.demo4.Person">
        <property name="name" value="李四"/>
        <property name="age" value="32"/>
        <property name="cat" ref="cat"/>
  </bean>

    <bean id="cat" class="com.imooc.ioc.demo4.Cat">
        <property name="name" value="ketty"/>
    </bean>
P名称空间的属性注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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的p名称空间的属性注入==============================-->
    <bean id="person" class="com.imooc.ioc.demo4.Person" p:name="大黄" p:age="34" p:cat-ref="cat"/>

    <bean id="cat" class="com.imooc.ioc.demo4.Cat" p:name="小黄"/>
       
</beans>
SpEL:spring expression language对依赖注入进行简化
- 语法:#{表达式}
  <bean id="" value="#{表达式}">
- SpEL表达式语言

语法:#{}
#{‘hello’} :使用字符串
#{topicId3}: 使用另一个bean
#{topicId4.content.toUpperCase()}:使用指定名属性,并使用方法.
#{T(java.lang.Math).PI}: 使用静态字段或方法
/**
商品类
*/
public class Product {
    private String name;
    private Double price;

    private Category category;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", category=" + category +
                '}';
    }
}

* * *
/**
商品分类
*/
public class Category {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Category{" +
                "name='" + name + '\'' +
                '}';
    }
}

* * *
public class ProductInfo {

    public Double calculatePrice(){
        return Math.random() * 199;
    }
}

* * *
public class SpringDemo4 {
    @Test
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product)applicationContext.getBean("product");
        System.out.println(product);
    }
 }
<!--Bean的SpEL的属性注入==============================-->
    <bean id="category" class="com.imooc.ioc.demo4.Category">
        <property name="name" value="#{'服装'}"/>
    </bean>

    <bean id="productInfo" class="com.imooc.ioc.demo4.ProductInfo"/>

    <bean id="product" class="com.imooc.ioc.demo4.Product">
        <property name="name" value="#{'男装'}"/>
        <property name="price" value="#{productInfo.calculatePrice()}"/>
        <property name="category" value="#{category}"/>
    </bean>
复杂类型的属性注入
  • 数组类型的属性注入
  • List集合类型的属性注入
  • Set集合类型的属性注入
  • Map集合类型的属性注入
  • Properties类型的属性注入
public class CollectionBean {
    private String[] arrs; // 数组类型

    private List<String> list;// List集合类型

    private Set<String> set; // Set集合类型

    private Map<String,Integer> map;// Map集合类型

    private Properties properties; // 属性类型

    public String[] getArrs() {
        return arrs;
    }

    public void setArrs(String[] arrs) {
        this.arrs = arrs;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, Integer> getMap() {
        return map;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arrs=" + Arrays.toString(arrs) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

* * *
public class SpringDemo5 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

       CollectionBean collectionBean = (CollectionBean)applicationContext.getBean("collectionBean");

       System.out.println(collectionBean);
    }
}
<!--集合类型的属性注入=================================-->
    <bean id="collectionBean" class="com.imooc.ioc.demo5.CollectionBean">
        <!--数组类型-->
        <property name="arrs">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
        <!--List集合的属性注入-->
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
                <value>333</value>
            </list>
        </property>
        <!--Set集合的属性注入-->
        <property name="set">
            <set>
                <value>ddd</value>
                <value>eee</value>
                <value>fff</value>
            </set>
        </property>
        <!--Map集合的属性注入-->
        <property name="map">
            <map>
                <entry key="aaa" value="111"/>
                <entry key="bbb" value="222"/>
                <entry key="ccc" value="333"/>
            </map>
        </property>
        <!--Properties的属性注入-->
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">1234</prop>
            </props>
        </property>
    </bean>

5.Spring的bean管理(注解方式)

1.使用注解定义Bean

@Repository 用于对DAO实现类进行标注

@Service 用于对Service实现类进行标注

@Controller 用于对Controller实现类进行标注

6.Spring的属性注入(注解方式)

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.4.RELEASE</version>
 </dependency>
 
 JAR依赖
/**
 * Spring的Bean管理的注解方式:
 *  * 传统方式需要去XML中配置<bean id="" class=""></bean>
 */
@Service("userService")
public class UserService {
    @Value("米饭")
    private String something;
    
    @Resource(name="userDao")
    private UserDao userDao;

    public String sayHello(String name){
        return "Hello" + name;
    }

    public void eat(){
        System.out.println("eat:"+something);
    }

    public void save(){
        System.out.println("Service中保存用户...");
        userDao.save();
    }
}

* * *
@Repository("userDao")
public class UserDao {

    public void save(){
        System.out.println("DAO中保存用户...");
    }
}

* * *
public class SpringDemo1 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService) applicationContext.getBean("userService");

        String s = userService.sayHello("张三");

        System.out.println(s);
    }

    @Test
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.eat();
    }

    @Test
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService) applicationContext.getBean("userService");

        userService.save();
    }
}
<?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.xsd">

    <!--开启注解扫描=======================-->
<context:component-scan base-package="com.imooc"/>
</beans>

7.其他注解

@Component("bean1")
public class Bean1 {

    @PostConstruct
    public void init(){
        System.out.println("initBean...");
    }

    public void say(){
        System.out.println("say...");
    }

    @PreDestroy
    public void destory(){
        System.out.println("destoryBean...");
    }
}

* * *
@Component("bean2")
@Scope("prototype") //来指定是否单例或者多例
public class Bean2 {

}

* * *
public class SpringDemo2 {
    @Test
    public void demo1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");

        bean1.say();

        applicationContext.close();
    }

    @Test
    public void demo2(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        Bean2 bean1 = (Bean2)applicationContext.getBean("bean2");
        Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");

        System.out.println(bean1 == bean2);

    }
}

8、关于xml和注解整合开发

/*
商品业务层的类
*/
public class ProductService {
    @Resource(name="categoryDao")
    private CategoryDao categoryDao;

    @Resource(name="productDao")
    private ProductDao productDao;

/*    public void setCategoryDao(CategoryDao categoryDao) {
        this.categoryDao = categoryDao;
    }

    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }*/

    public void save(){
        System.out.println("ProductService的save方法执行了...");
        categoryDao.save();
        productDao.save();
    }
}

* * *
public class CategoryDao {
    public void save(){
        System.out.println("CategoryDao中的save方法执行了...");
    }
}

* * *
public class ProductDao {
    public void save(){
        System.out.println("ProductDao的save方法执行了...");
    }
}

* * *
public class SpringDemo3 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        ProductService productService = (ProductService)applicationContext.getBean("productService");

        productService.save();
    }
}
<?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.xsd">

    <!--开启注解扫描=======================-->
<!--    <context:component-scan base-package="com.imooc"/>-->

    <context:annotation-config/>

    <bean id="productService" class="com.imooc.demo3.ProductService">
       <!-- <property name="productDao" ref="productDao"/>
        <property name="categoryDao" ref="categoryDao"/>-->
    </bean>

    <bean id="productDao" class="com.imooc.demo3.ProductDao"/>

    <bean id="categoryDao" class="com.imooc.demo3.CategoryDao"/>
</beans>

猜你喜欢

转载自www.cnblogs.com/Guard9/p/11105497.html