>  기사  >  백엔드 개발  >  Java 프로그래밍 구성 아이디어에 대한 자세한 설명 - JavaEE 튜토리얼

Java 프로그래밍 구성 아이디어에 대한 자세한 설명 - JavaEE 튜토리얼

不言
不言원래의
2018-03-30 10:35:371604검색

이 기사는 주로 Java 프로그래밍 구성 아이디어에 대한 자세한 설명을 공유합니다. Java를 배우는 친구들에게 도움이 되기를 바랍니다.

Java 프로그래밍 구성 아이디어에 대한 자세한 설명

SpringBoot는 개발에 도움이 되는 많은 훌륭한 스타터를 제공합니다. 실제로는 프로덕션 환경의 특수성으로 인해 프로그램의 제어 가능성을 향상시키기 위해 기본 통합 구성을 사용자 정의해야 하지만 구성이 공식 스타터보다 낫지 않을 수도 있습니다. 지난주에는 작업 및 장식 문제로 인해 블로그가 정상적으로 업데이트되지 않았습니다. 업데이트를 중단하면 사람들이 게을러질까 봐 조금 시간을 내어 비교적 간단한 글을 작성했습니다. 나중에 장식 초보자부터 시작하기까지의 경험에 대해 이야기하겠습니다.

Technology: Configuration, ComponentScan, PropertySource, EnableTransactionManagement, Bean, Value
Note: 구성 코드만 기사에 게시되었으며 전체 테스트 코드는 github에 있습니다.
소스 코드:https://github.com/ITDragonBl...
문서 디렉토리 구조:

Java 프로그래밍 구성 아이디어에 대한 자세한 설명 - JavaEE 튜토리얼

1. Java 프로그래밍 구성

Spring 4.x 이전에는 Java 프로그래밍 구성의 기본 구성은 다음과 같습니다. 애플리케이션은 일반적으로 xml 구성을 사용했으며 비즈니스 로직에서는 주석을 사용하는 것이 좋습니다. 그러나 Spring 4.x 이후 관계자들은 xml 구성 대신 Java 프로그래밍 구성을 사용하도록 권장하기 시작했습니다. 이 두 구성의 장점과 단점은 무엇입니까?

Java 프로그래밍 구성 및 xml 구성

Xml 구성의 장점: 이전 세대 프로그래머(┬_┬)에게 xml은 매우 친숙하고, 사용하기 쉽고, 확장하기 쉽고, 애플리케이션 구성 매개변수를 수정하기 위해 다시 컴파일할 필요가 없습니다.

xml 구성의 단점: 구성 파일을 읽고 구문 분석하는 데 시간이 걸리고, 내용이 너무 많은 xml 구성 파일은 비대해 보이고 관리하기 불편해집니다.

Java 프로그래밍 구성의 장점: xml 구성과 비교하여 구조가 더 명확하고 읽기 쉬우며 xml 구문 분석 시간도 절약됩니다.

Java 프로그래밍 구성의 단점: 애플리케이션 구성 매개변수를 수정하려면 다시 컴파일해야 합니다. 실제로 실제 프로덕션 환경에서는 애플리케이션 구성이 완료된 후 일반적으로 사람들이 이를 마음대로 수정하지도 않고 감히 수정하지도 않습니다.

둘 다 나름의 장점이 있는데, Spring 4.x와 Spring Boot 모두 Java 프로그래밍 구성 사용을 권장한다는 점을 고려하면 꼭 사용할 필요는 없지만 이해해야 합니다.

Java 프로그래밍 구성 단계

첫 번째 단계: 구성 클래스 생성, 클래스 이름에 주석 구성 추가, 이것이 구성 클래스이고 해당 기능이 xml 파일과 유사함을 Spring에 알립니다.

두 번째 단계: 로드 외부 구성 파일, 클래스의 이름에 PropertySource 주석을 추가하고 속성 파일의 읽기 경로를 지정합니다

3단계: 애플리케이션 구성 속성 값을 가져오고 속성 변수에 주석 값을 추가한 다음 매개변수를 가져옵니다. ${} 표현식을 통해 구성 파일

4단계: 종속성 주입을 위해 메서드에 Bean 주석을 추가하거나 FactoryBean

을 사용할 수 있습니다. 첫 번째와 네 번째 단계의 구문은 두 번째에서 자세히 소개됩니다. 기사의 일부. 두 번째 및 세 번째 단계의 구문은 기사의 세 번째 부분에서 자세히 소개됩니다.

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * Spring 配置类
 * 配置数据源,事务管理,bean,自动扫描包
 * @author itdragon
 */
@Configuration    // 声明该类为配置类
@PropertySource({"classpath:propertySource.properties"})    // 引入外部文件
@ComponentScan("com.itdragon")    // 配置自动扫描包的路径
@EnableTransactionManagement    // 开启基于注解的事务管理功能
public class ApplicationContextConfig {
    
    @Value("${DATA_USER}")
    private String DATA_USER;
    
    @Value("${DATA_PAWD}")
    private String DATA_PAWD;
    
    @Value("${DATA_DRIVER}")
    private String DATA_DRIVER;
    
    @Value("${DATA_JDBC_URL}")
    private String DATA_JDBC_URL;
    
    @Bean // 数据源
    public DataSource dataSource() throws Exception{
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(DATA_USER);
        dataSource.setPassword(DATA_PAWD);
        dataSource.setDriverClass(DATA_DRIVER);
        dataSource.setJdbcUrl(DATA_JDBC_URL);
        return dataSource;
    }
    
    @Bean // jdbc模板
    public JdbcTemplate jdbcTemplate() throws Exception{
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }
    
    @Bean // 事务管理
    public PlatformTransactionManager transactionManager() throws Exception{
        return new DataSourceTransactionManager(dataSource());
    }

}

트랜잭션 클래스

import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itdragon.dao.ITDragonDao;

@Service
public class ITDragonServer {
    
    @Autowired(required=false)
    private ITDragonDao itdragonDao;

    public List<Map<String,Object>> findAll() {
        return itdragonDao.findAll();
    }
    
    @Transactional
    public void updateNameById(String name, Long id) {
        itdragonDao.updateUserNameById(name, id);
        System.out.println(0/0); // 事务异常
    }
}

전체 코드는 비동기식 github

로 부탁드립니다. 2. 컴포넌트 주입

Bean 주석은 xml 파일의 60e23eb984d18edbb092da6b8f295aba标签,其中被Bean注解修饰的方法名对应60e23eb984d18edbb092da6b8f295aba 태그에 있는 id와 유사합니다. Bean 주석의 값 속성입니다. 이는 SpringBoot의 기본 코드에서 널리 사용됩니다.

컨테이너가 시작된 후 객체를 생성하고 사용 후 컨테이너에서 직접 얻으려면 아무것도 할 필요가 없습니다. Spring은 기본적으로 단일 인스턴스, 즉 객체가 생성된 후에 생성되기 때문입니다. 컨테이너가 시작되고 컨테이너에 저장된 후 다시 컨테이너에서 가져옵니다.

컨테이너 시작 후 객체가 생성되지 않고, 사용 시 객체가 생성되어 컨테이너에 저장되었다가 다음 사용 시 컨테이너에서 검색되도록 하려면 지연 로딩을 통해 달성할 수 있습니다. 즉, Lazy 주석으로 수정되었습니다.

컨테이너가 시작된 이후에 객체가 생성되지 않고, 사용될 때마다 객체가 생성되기를 바라는 경우에는 다중 인스턴스 방식, 즉 Scope 주석을 사용하고, 매개변수의 값은 프로토타입, 즉 @Scope("프로토타입")입니다.

컨테이너가 시작된 후 조건에 따라 주입해야 하는 Bean을 선택하려면 조건부 주석을 사용하여 SpringBoot의 기본 평가에서 이 주석을 사용하면 됩니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Controller;
import com.itdragon.entity.ITDragonEntity;
import com.itdragon.server.ITDragonServer;

/**
 * 知识点二:配置自动扫描包路径
 * 一、注解ComponentScan的value值设置自动扫描包的路径
 * 二、注解ComponentScan的excludeFilters值设置扫描排除的规则
 *     1)、通过注解@Filter设置排除的类型,type=ANNOTATION表示按照注解包含排除。classes是具体的注解,如Controller,Server,Repository
 * 三、注解ComponentScan的includeFilters值设置扫描加入的规则
 *  1)、通过设置useDefaultFilters=false关闭Spring默认扫描全部的功能,使includeFilters生效
 *  
 * 知识点三:@Filter常用的拦截类型
 * 一、FilterType.ANNOTATION:按照注解
 * 二、FilterType.ASSIGNABLE_TYPE:按照给定的类型,包括其子类和实现类
 * 三、FilterType.CUSTOM:使用自定义规则
 * 
 * 第一个ComponentScan注解表示在指定包下不扫描通过Controller注解修饰的类和ITDragonServer类及其子类和实现类
 * 第二个ComponentScan注解表示在指定包下只扫描通过Controller注解修饰的类
 * 第三个ComponentScan注解表示在指定包下根据自定义拦截规则,不扫描满足规则的类
 */
@Configuration
@ComponentScan(value="com.itdragon",excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
        @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={ITDragonServer.class})})
//@ComponentScan(value="com.itdragon",includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class})},useDefaultFilters=false)
//@ComponentScan(value="com.itdragon",excludeFilters={@Filter(type=FilterType.CUSTOM,classes={ITDragonCustomTypeFilter.class})})
public class ITDragonConfig {
    
    /**
     * 知识点一:配置bean
     * 一、注解Bean的value值表示bean的id
     * 二、注解Bean的value值未设置,则方法名表示bean的id
     */
    @Bean(value="itdragonBean")
    public ITDragonEntity itdragonEntity() { //方法名很重要,类似xml的id名,也可以通过@bean的value值重定义
        return new ITDragonEntity("itdragon", "configuration-password", 25);
    }
    
    /**
     * 知识点四:Scope属性
     * @Scope,调整作用域,默认单实例
     * singleton:单实例:ioc容器启动后创建对象放到ioc容器中,需要是从容器中获取。
     * prototype:多实例:ioc容器启动后每次获取对象时都要创建对象。
     * request:同一次请求创建一个实例
     * session:同一个session创建一个实例
     * 
     * 知识点五:懒加载
     * 针对单实例而言,在容器启动后不创建对象,在第一次使用Bean时创建对象。可以理解为单实例的一种补充。
     * 
     */
//    @Scope("prototype")
    @Lazy
    @Bean
    public ITDragonEntity scopeTopicBean() {
        System.out.println("^^^^^^^^^^^^^^^^^^^^^Create Bean");
        return new ITDragonEntity("scopeBean", "singleton-prototype-request-session", 25);
    }
    
    /**
     * 知识点六:Conditional条件判断
     * 满足条件才会注册bean,可以修饰在类上,管理整个类下的组件注入。
     */
    @Bean
    @Conditional({ITDragonCustomCondition.class})
    public ITDragonEntity conditionalBean() {
        return new ITDragonEntity("conditionalBean", "Conditional-Condition-CustomCondition", 25);
    }
    
    /**
     * 知识点七:FactoryBean工厂Bean
     * FactoryBean默认通过调用getObject创建的对象,通过调用isSingleton设置单实例和多实例。
     */
    @Bean
    public ITDragonFactoryBean itdragonFactoryBean() {
        return new ITDragonFactoryBean();
    }
}

맞춤형 조건부 판단 컴포넌트 주입 클래스

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * 自定义的条件判断组件注入
 * @author itdragon
 *
 */
public class ITDragonCustomCondition implements Condition{

    /**
     * 判断注册的bean中是否含有指定的bean
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 获取bean的注册类
        BeanDefinitionRegistry registry = context.getRegistry();
        return registry.containsBeanDefinition("scopeTopicBean"); // 有则加载conditionalBean
    }

}

맞춤형 Bean 팩토리 클래스

import org.springframework.beans.factory.FactoryBean;
import com.itdragon.entity.ITDragonEntity;
/**
 * 自定义Bean的工厂类
 * @author itdragon
 *
 */
public class ITDragonFactoryBean implements FactoryBean<ITDragonEntity>{

    public ITDragonEntity getObject() throws Exception {
        System.out.println("^^^^^^^^^^^^^^^^^^^^^FactoryBean Create Bean");
        return new ITDragonEntity(); // 创建对象并返回到容器中
    }

    public Class<?> getObjectType() {
        return ITDragonEntity.class;
    }

    public boolean isSingleton() {
        return false; // 设置多实例,true则为单例
    }

}

3. 속성 할당

속성 할당 단계:

1단계: PropertySource 주석을 통해 외부 파일을 도입합니다. 여러 파일을 도입할 수 있습니다. 파일이 존재하지 않는 경우에는ignoreResourceNotFound 매개변수를 통해 무시할 수 있습니다. 2단계: 일반적으로 ${} 형식을 사용하여 주석 값을 통해 외부 파일에서 값을 가져옵니다. #{} SpEL 표현식도 지원하며 문자열을 직접 전달할 수도 있습니다. 컬렉션과 같은 일부 복잡한 값을 받으려면 ConfigurationProperties 주석을 사용하는 것이 좋습니다. 두 가지의 장점과 단점은 나중에 자세히 소개하겠습니다.

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;
import com.itdragon.entity.ITDragonEntity;

/**
 * 知识点一: 引入外部文件,并从文件中获取值
 * @PropertySource 引入外部文件,支持多个,如果文件不存在会报错,可以通过设置参数ignoreResourceNotFound=true忽略
 * @Value 从外部文件中获取值,支持spel表达式,#{},${},string
 * @author itdragon
 */
@Configuration
@PropertySource(value={"classpath:propertySource.properties","classpth:xxx.properties"},ignoreResourceNotFound=true)
public class ITDragonConfigValue {
    
    @Value("${ACCOUNT}")        // 从配置文件获取数据
    private String ACCOUNT;
    
    @Value("${PASSWORD}")
    private String PASSWORD;
    
    @Value("${AGE}")
    private Integer AGE;
    
    @Value("ITDragon")            // 普通赋值
    private String str;
    
    @Value("#{(1+2-3)/4*5}")    // 算术运算
    private String operator;
    
    @Value("#{1>2 || 2 <= 3}")    // 关系运算
    private Boolean comparison;
    
    @Value("#{systemProperties[&#39;java.version&#39;]}") // 系统配置:os.name
    private String systemProperties;
    
    @Value("#{T(java.lang.Math).abs(-18)}")    // 表达式
    private String mapExpression;
    
    @Bean("valueBean")
    public ITDragonEntity itdragonEntity() {
        System.out.println("^^^^^^^^^^^^^^^^^^^^ str : " + str);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ operator : " + operator);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ comparison : " + comparison);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ systemProperties : " + systemProperties);
        System.out.println("^^^^^^^^^^^^^^^^^^^^ mapExpression : " + mapExpression);
        return new ITDragonEntity(ACCOUNT, PASSWORD, AGE);
    }

}

四、闲谈学习

这里并不是介绍如何学习一门技术,而是论养成一个学习习惯的重要性。大一时期,因为担心找不到工作而报了一个线上培训机构。经常被洗脑,其中一句话而我印象深刻 ---- "让优秀成为一种习惯"。听得我热血沸腾。花了五六千大洋报名,后来才发现网上有免费的。。。。个人不建议参加培训

这钱花的还算值得,"让优秀成为一种习惯",这句话对我的影响很大,从大学到工作,每当遇到陌生的知识,并没有选择逃避它。而是抽时间从网上找资料,去学习,整理,实践直到弄懂它。可我万万没有想到,这种学习的精神竟然用到了装修上。。。。可能学习已经是我的一个习惯了吧

开始,我是一个装修小白,不知道什么是全包、半包、清包;不知道什么是硬装、软装;也不知道装修的流程;不知道水电线、橱柜、洁具的品牌选择,不知道挂机、柜机、风管机、中央空调的优缺点;不知道封阳台的利弊;更不知道一个装修效果图要七八千。面对这些未知的领域,我寸步难行。我清楚的知道:如果你不懂,你就是砧板上的鱼肉,任人宰割。

现在,我通过在百度,知乎,兔巴兔等平台上找答案,并把内容用Markdown的格式整理!我都被自己吓到了。不仅如此,我还在抢设计师的饭碗,自己动手设计效果图。在制作效果图的过程中,发现了很多不合理的设想。庆幸问自己设计了一套效果图,不然又有很多无用功,耗时,耗力,耗钱。爸妈和女票就是客户,而我就一直处于改!改!改!的阶段。体验了一把前端工程师的辛酸。

我是谁?我在哪?我在做什么?

我是一名程序员,我在学习的道路上,我在做能提高自己的事情!


相关推荐:



위 내용은 Java 프로그래밍 구성 아이디어에 대한 자세한 설명 - JavaEE 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.