Spring:高级注解

@Configuration注解:配置Bean 

配置Bean就是为了取代配置文件,不用写ApplicationContext.xml了,所以Configuration不会用<context:标签在配置文件中扫描注解@Configuration

 

@Bean注解是在配置Bean:@Configuration中用来创建对象的

Spring针对复杂对象用FactoryBean来创建

Scope=“”控制对象创建次数

 

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.itheima</groupId>
  <artifactId>spring11</artifactId>
  <version>1.0-SNAPSHOT</version>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>6</source>
          <target>6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <!--        引入事务依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.1.14.RELEASE</version>
    </dependency>
    <!--        junit依赖-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--spring依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.14.RELEASE</version>
    </dependency>

    <!--引入log4j日志坐标-->
<!--
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.7.25</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.logback-extensions</groupId>
      <artifactId>logback-ext-spring</artifactId>
      <version>0.1.4</version>
    </dependency>

    <!--        Spring与MyBatis整合依赖需要导入-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.1.14.RELEASE</version>
    </dependency>
    <!--mybatis与spring依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.2</version>
    </dependency>
    <!--连接池依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.18</version>
    </dependency>




    <!--        引入mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.48</version>
    </dependency>
    <!--        引入mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>


    <!--        引入动态代理-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.1.14.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.8.8</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.3</version>
    </dependency>
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>


</project>

日志文件:logback.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!-- 控制台输出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

 User:

package com.baizhiedu.bean;

public class User {
}

ConnectionFactoryBean

package com.baizhiedu.bean;

import org.springframework.beans.factory.FactoryBean;

import java.sql.Connection;
import java.sql.DriverManager;

public class ConnectionFactoryBean implements FactoryBean<Connection> {


    @Override
    public Connection getObject() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/myBatis?useSSL=false","root","123456");
        return conn;
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;//返回复杂对象的class对象
    }

    @Override
    public boolean isSingleton() {
        return false;//控制创建次数,每次都创建新的
    }
}

AppConfig:

package com.baizhiedu;

import com.baizhiedu.bean.ConnectionFactoryBean;
import com.baizhiedu.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;

@Configuration //@Configuration注解,代表它是一个配置Bean,代替applicationContext.xml
public class AppConfig {

    //简单对象
    //通过Bean注解创建User对象 user代表原来配置文件的id值 User代表创建对象类型
    //方法名字作为默认的id值 如果想要改变可以在@Bean("u") u作为id值
    @Bean("u")
    @Scope("prototype")//控制对象创建次数,每一次都让spring创建新的对象 prototype创建多次 singleton创建一次
    public User user(){
        return new User();
    }

    //复杂对象
    /*
      Connection 不能直接通过new 创建
      Connection 不能直接通过new 创建
     */
    @Bean
    public Connection conn(){
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/myBatis?useSSL=false","root","123456");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;

    }

    //FactoryBean跟@Bean集成
    @Bean
    public Connection conn1(){
        Connection conn = null;//通过方法调用获得复杂对象
        try {
            ConnectionFactoryBean FactoryBean=new ConnectionFactoryBean();
            conn = FactoryBean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

}

UserDAO:

package com.baizhiedu.injection;

public interface UserDAO {
    public void save();
}

UserDAOImpl:

package com.baizhiedu.injection;

public class UserDAOImpl implements UserDAO {
    @Override
    public void save() {
        System.out.println("UserDAOImpl.save");
    }
}

UserService:

package com.baizhiedu.injection;

public interface UserService {
    public void register();
}

UserServiceImpl:

package com.baizhiedu.injection;




public class UserServiceImpl implements UserService {
    private UserDAO userDAO;

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public void register() {
        userDAO.save();
    }
}

AppConfig1:

package com.baizhiedu;

import com.baizhiedu.bean.Customer;
import com.baizhiedu.injection.UserDAO;
import com.baizhiedu.injection.UserDAOImpl;
import com.baizhiedu.injection.UserService;
import com.baizhiedu.injection.UserServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration //注解配置Bean
@PropertySource("classpath:/init.properties")//注解读取配置文件,来解下面给JDK类型注入时候的耦合
public class AppConfig1 {

    @Value("${id}")  //@Value注解为id属性赋值
    private Integer id;
    @Value("${name}")
    private String name;

    //自定义类型注入
    @Bean
    public UserDAO userDAO(){
        return new UserDAOImpl();
    }

    /*@Bean  //通过给UserService方法传递一个参数,再进行setUserDAO(userDAO)的注入赋值
    public UserService userService(UserDAO userDAO){
        UserServiceImpl userService=new UserServiceImpl();
        userService.setUserDAO(userDAO);
        return userService;
    }*/

    //第二种注入写法不用传一个参数
    @Bean  //通过给UserService方法传递一个参数,再进行setUserDAO(userDAO)的注入赋值
    public UserService userService(){
        UserServiceImpl userService=new UserServiceImpl();
        userService.setUserDAO(userDAO());//这里调用userDAO()方法
        return userService;
    }

    // 简单对象,JDK类型注入
    @Bean
    public Customer customer(){
        Customer customer=new Customer();
//        customer.setId(1);
//        customer.setName("xiaohei");

        //通过配置文件,进行注入,来解耦合
        customer.setId(id);
        customer.setName(name);
        return customer;
    }
}

init.properties:

id=2
name=suns

TestAnnotation:

package com.baizhiedu;

import com.baizhiedu.bean.Customer;
import com.baizhiedu.bean.User;
import com.baizhiedu.injection.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.sql.Connection;

public class TestAnnotation {
    //用于测试:配置Bean
    @Test
    public void test1(){
        //ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);//可以直接指定那个配置Bean的class
        ApplicationContext ctx=new AnnotationConfigApplicationContext("com.baizhiedu");//工厂扫描配置com.baizhiedu这个包,查找具有@Configuration注解类型
    }

    //用于测试:@Bean注解 创建简单对象
    @Test
    public void test2(){
        //ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);//可以直接指定那个配置Bean的class
        ApplicationContext ctx=new AnnotationConfigApplicationContext("com.baizhiedu");
        User user=(User)ctx.getBean("u");
        System.out.println(user);
    }
    //用于测试:@Bean注解 创建复杂对象
    @Test
    public void test3(){
        //ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);//可以直接指定那个配置Bean的class
        ApplicationContext ctx=new AnnotationConfigApplicationContext("com.baizhiedu");
        Connection conn=(Connection)ctx.getBean("conn");
        System.out.println("conn:"+conn);
    }

    //用于测试:@Bean注解 创建复杂对象 FactoryBean创建复杂对象和@Bean集成
    @Test
    public void test4(){
        //ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);//可以直接指定那个配置Bean的class
        ApplicationContext ctx=new AnnotationConfigApplicationContext("com.baizhiedu");
        Connection conn1=(Connection)ctx.getBean("conn1");
        System.out.println("conn1:"+conn1);
    }

    //用于测试:测试User对象的创建次数
    @Test
    public void test5(){
        //ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);//可以直接指定那个配置Bean的class
        ApplicationContext ctx=new AnnotationConfigApplicationContext("com.baizhiedu");
        User user1=(User)ctx.getBean("u");
        User user2=(User)ctx.getBean("u");
        System.out.println("user1="+user1);
        System.out.println("user2="+user2);
    }

    //用于测试:@Bean注解:自定义类型注入
    @Test
    public void test6(){
        ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig1.class);//可以直接指定那个配置Bean的class
        UserService userService=(UserService)ctx.getBean("userService");
        userService.register();
    }

    //用于测试:@Bean注解:JDK类型注入
    @Test
    public void test7(){
        ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig1.class);//可以直接指定那个配置Bean的class
        Customer customer=(Customer)ctx.getBean("customer");
        System.out.println("customer="+customer.getId());
        System.out.println("customer="+customer.getName());
    }
}

 test2:

 test3:

test4:

 test5:注解使用的创建对个对象,所以对象不一样

 test6:

t est7:

设置注解扫描:注解

注解排除

注解扫描:

User1:

package com.baizhiedu.scan;

import org.springframework.stereotype.Component;

@Component
public class User1 {
}

User2:

package com.baizhiedu.scan;

import org.springframework.stereotype.Service;

@Service
public class User2 {
}

AppConfig2:

package com.baizhiedu;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Service;

@Configuration //配置Bean注解
//为了扫描曾经讲过的基础注解,使其生效,扫描com.baizhiedu.scan包下的所有注解
@ComponentScan(basePackages = "com.baizhiedu.scan",
               excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}),
                                 @ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = "*..User1")})//excludeFilters ={}注解排除排除@Service注解
public class AppConfig2 {
}

TestAnnotation2:

package com.baizhiedu;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestAnnotation2 {
    //用于测试:@    componentScan 扫描基础注解的使用
    @Test
    public void test1(){
        ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig2.class);
        String[] beanDefinitionNames=ctx.getBeanDefinitionNames();//获取所有对象的id
        for (String beanDefinitionName:beanDefinitionNames){
            System.out.println("beanDefinitionName="+beanDefinitionName);
        }
    }
}

test1:当没有写排除注解是,输出基础注解创建的对象:

当AppConfig2中写上排除注解后:

 

注解包含:

AppConfig:注释类排除注解,使用包含把@Service注解的对象包含进来

package com.baizhiedu;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Service;

@Configuration //配置Bean注解
//为了扫描曾经讲过的基础注解,使其生效,扫描com.baizhiedu.scan包下的所有注解

/*
注解扫描,注解排除
@ComponentScan(basePackages = "com.baizhiedu.scan",
               excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}),
                                 @ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = "*..User1")})//excludeFilters ={}注解排除排除@Service注解
*/
/*
 注解扫描 注解包含
 useDefaultFilters = false,不使用默认扫描,用include-filter扫描方式
 */
@ComponentScan(basePackages = "com.baizhiedu.scan",useDefaultFilters = false,
               includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class})})
public class AppConfig2 {
}

 test1:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喵俺第一专栏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值